【问题标题】:Getting a segmentation fault while reading from file从文件读取时出现分段错误
【发布时间】:2020-08-14 01:39:52
【问题描述】:

我正在处理结构和字符指针(字符串)。我想创建一个结构数组,这些结构有一个char* 和两个ints。

尝试将fscanf 插入arraystructs 时遇到分段错误。

这是我的代码的相关部分。

结构定义

typedef struct {
    char* title;
    int gross;
    int year;
} Movie;

我遇到问题的函数

Movie* createArray(char *filename, int size)
{

    FILE *f;
    f = fopen(filename, "r");
    Movie* arr = (Movie*) malloc(sizeof(Movie) * size);
    if(!arr){printf("\nAllocation Failed\n"); exit(1);}
    for (int i =0; i<size; i++){
        fscanf(f, "%s %d %d", (arr+ i)->title, &arr[i].gross, &arr[i].year);
    }
    fclose(f);
    return arr;

}

添加到这里以防万一是我调用函数的方式

        Movie* arr = createArray(file1, records);

【问题讨论】:

  • title 是一个指针,你需要为它预留内存或者直接声明为一个字符数组:
  • 您可能想要选择指针表示法或索引表示法,在(arr+ i)-&gt;title, &amp;arr[i].gross, &amp;arr[i].year 中两者都看起来很尴尬——这没什么问题,只是读起来有点奇怪。
  • @CRedmond,我注意到您已经在网站上提出了一些问题,但您还没有问过accept an answer 尽管有几个很好的问题,接受答案是该网站的一个重要功能,而不是不仅它奖励发布者,而且还表明解决了问题为未来观众提出的问题的答案。

标签: c pointers struct segmentation-fault allocation


【解决方案1】:

我想在你的函数中解决一些其他问题,其中一些你可能知道,下面的代码使用 cmets。

Movie* createArray(char *filename, int size)
{
    FILE *f;

    if(!(f = fopen(filename, "r"))){ //also check for file opening
        perror("File not found");
        exit(EXIT_FAILURE); //or return NULL and handle it on the caller
     }  

    //don't cast malloc, #include <stdlib.h>, using the dereferenced pointer in sizeof
    //is a trick commonly  used to avoid future problems if the type needs to be changed
    Movie* arr = malloc(sizeof(*arr) * size);    

    if(!arr) {
        perror("Allocation Failed"); //perror is used to output the error signature
        exit(EXIT_FAILURE);
    }

    for (int i =0; i<size; i++) {
        if(!((arr + i)->title = malloc(100))){ // 99 chars plus null terminator, 
            perror("Allocation failed");       // needs to be freed before the array
            exit(EXIT_FAILURE);   //using EXIT_FAILURE macro is more portable 
        }

        //always check fscanf return, and use %99s specifier 
        //for 100 chars container to avoid overflow
        if(fscanf(f, "%99s %d %d", (arr+ i)->title, &arr[i].gross, &arr[i].year) != 3){ 
            exit(EXIT_FAILURE); //or return NULL and handle it on the caller
        }
    }
    fclose(f);
    return arr;
}

【讨论】:

  • 很好的答案,除了我还要修复arr-nullcheck 行中的间距。另外,在释放数组本身之前,不要忘记为数组的每个元素释放 title
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-06-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多