Question

When I am executing printf command for level->description, the program gives me segmentation fault. I don't know why. Should I use malloc to repair it? The content (only 1 line ending with '\n') of file sokoban.dat is "chicago;addie;story begins here;-----#####-----------|-----#@$.#-----------|-----#####-----------"

#include<stdio.h>
#include<stdlib.h>
#include<string.h>

typedef struct {
char *name;
char *description;
char *password;
char *map;
struct level *next;
//char *solution;
} LEVEL;

LEVEL* parse_level(char *line) {   //parsing from file into the structure
    LEVEL level;
    char level_name[50];
    char level_password[50];
    char level_description[100];
    char level_map[200];

    int i = 0;
    int j = 0;
    while (line[i] != ';') {      //getting level name
        level_name[j] = line[i];
        i++;
        j++;
    }
    level_name[j]='\0';
    level.name=&level_name[0];
    //strcpy(&level.name,level_name);
    //printf("%s\n",level.name);
    printf("%s\n",level_name);
    j = 0;
    i++;
    while (line[i] != ';') {     //getting level password
        level_password[j] = line[i];
        i++;
        j++;
    }
    level_password[j]='\0';
    level.password=&level_password[0];
    printf("%s\n",level_password);
    j = 0;
    i++;
    while (line[i] != ';') {     //getting level description
        level_description[j] = line[i];
        i++;
        j++;
    }
    level_description[j]='\0';
    level.description=&level_description[0];
    printf("%s\n",level_description);
    j = 0;
    i++;
    while (line[i] != '\n') {    //getting level map
        level_map[j] = line[i];
        i++;
        j++;
    }
    level_map[j]='\0';          
    level.map=&level_map[0];
    printf("%s\n",level_map);
    j = 0;
    level.next=NULL;    
    LEVEL* levelPointer=&level;
    return levelPointer;
}  
int main(){
    FILE *fp = fopen("sokoban.dat", "r");
    if( fp == NULL ){
        printf("No such file\n");
        return 1;
    }

    char line[500];
    //strcpy(line,"");
    char c;
    int i=0;
    while((c = fgetc(fp)) != '\n'){ //reading from file 1 by 1 character
       line[i]=c;
       i++;
    }
    printf("%s\n",line);
    LEVEL* level;
    level=parse_level(line);
    //printf("%s\n",level->description);   **//!!! this is where error occur**
    printf("%s\n",level->map);

    return 0;
}
Was it helpful?

Solution 2

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

typedef struct level {
    char *name;
    char *description;
    char *password;
    char *map;
    struct level *next;
    //char *solution;
} LEVEL;

#if 0
char *strdup(const char *str){
    size_t len = strlen(str);
    char *ret = malloc(len + 1);
    if(ret){
        memcpy(ret, str, len + 1);
        //ret[len] = '\0';
    }
    return ret;
}
#endif

LEVEL* parse_level(char *line) {
    //Returns the allocated memory
    LEVEL *level = malloc(sizeof(LEVEL));
    char *token;
    token=strtok(line, ";");//It cut the string as a separator the ';'.
    level->name = strdup(token);//Copy the memory allocated strings cut out.

    token=strtok(NULL, ";");//Get next token
    level->password = strdup(token);
    token=strtok(NULL, ";");
    level->description = strdup(token);
    token=strtok(NULL, ";");
    level->map = strdup(token);
    level->next = NULL;
#if DEBUG
    printf("debug print : level\n");
    printf("%s\n", level->name);
    printf("%s\n", level->password);
    printf("%s\n", level->description);
    printf("%s\n", level->map);
#endif
    return level;
}
void LEVEL_free(LEVEL *p){
    free(p->name);
    free(p->password);
    free(p->description);
    free(p->map);
    free(p);
}

int main(){
    FILE *fp = fopen("sokoban.dat", "r");
    if( fp == NULL ){
        printf("No such file\n");
        return 1;
    }

    char line[500];
    char c;
    int i=0;
    while((c = fgetc(fp)) != '\n'){ //reading from file 1 by 1 character
       line[i]=c;
       i++;
    }
    line[i] = '\0';
    printf("%s\n",line);
    LEVEL* level;
    level=parse_level(line);
    printf("%s\n",level->description);
    printf("%s\n",level->map);

    LEVEL_free(level);//free for malloced memory
    return 0;
}

OTHER TIPS

In the function, parse_level() you take addresses of all the local variables and copy into the struct variable level and return level. All these copy of local addresses and using those objects later after their lifetime make your program illegal and causes undefined behaviour.

You should read about basics of language first and understand concepts such as pointers, arrays, returning values from a function, returning pointers etc before diving deeper.

The ones related to your problems are:

returning a local variable from function in C

Since I can't return a local variable, what's the best way to return a string from a C or C++ function?

Undefined, unspecified and implementation-defined behavior

Undefined behavior and sequence points

The Definitive C Book Guide and List

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top