访问结构时的分段错误

时间:2014-05-09 22:49:23

标签: c parsing segmentation-fault

当我为level->描述执行printf命令时,程序会给我分段错误。我不知道为什么。我应该使用malloc进行修复吗?文件sokoban.dat的内容(只有1行以'\ n'结尾)是“chicago; addie;故事从这里开始; ----- ##### ----------- | -----#@$.#----------- | ----- ##### -----------“

#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;
}

2 个答案:

答案 0 :(得分:1)

在函数parse_level()中,您获取所有局部变量的地址并复制到struct变量level并返回level。所有这些本地地址副本以及稍后生命周期后使用这些对象会使您的程序非法并导致undefined behaviour

你应该首先阅读语言的基础知识,并在深入探讨之前理解指针,数组,函数返回值,返回指针等概念。

与您的问题相关的是:

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

答案 1 :(得分:0)

#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;
}