访问结构时出现分段错误

Posted

技术标签:

【中文标题】访问结构时出现分段错误【英文标题】:segmentation fault when accesing into a structure 【发布时间】:2014-05-09 22:49:23 【问题描述】:

当我为 level->description 执行 printf 命令时,程序给出了分段错误。我不知道为什么。我应该使用malloc来修复它吗?文件 sokoban.dat 的内容(只有 1 行以 '\n' 结尾)是 "chicago;addie;story started 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;

【问题讨论】:

使用诸如 gdb 之类的调试器来准确查找代码中的问题所在,或者注释掉程序的某些部分以缩小故障范围。就目前而言,其他 *** 用户不太可能非常努力地解决您的问题。 problematic 是倒数第 5 行(这是发生错误的时候)。我正在使用 NetBeans 进行调试和变量 level->description 它给了我地址:0x52 . 好的,那里面有 mul 终结器吗? (1)printf("%s\n",line); : line 不是以空结尾的。, (2) while((c = fgetc(fp)) != '\n')...while (line[i] != '\n') line 不包括\n 【参考方案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

【讨论】:

毫无疑问我应该多学习。最好的方法是通过例子学习。我会通过你提供的链接无论如何,Kernighan & Ritchie 的书很难吸收!【参考方案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;

【讨论】:

非常感谢您!.....我现在可以继续前进了。我不知道功能strtok()实际上有必要吗? #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 @Dounchan ;我写了不是标准函数的示例strdup。如果您的环境中已经存在(在 中),则不需要它。

以上是关于访问结构时出现分段错误的主要内容,如果未能解决你的问题,请参考以下文章

将结构插入地图时出现分段错误

访问填充了从管道读取的数据的结构时出现分段错误

访问共享内存时出现分段错误

删除时出现分段错误

[访问 我以前可以访问的功能时出现段错误

为啥在访问二级指针时出现分段错误错误? C语言