【问题标题】:Segmentation fault and realloc(): invalid next size: [duplicate]分段错误和 realloc():下一个大小无效:[重复]
【发布时间】:2014-02-21 23:17:49
【问题描述】:

我有一个程序,从键盘获取信息并将它们放入一个结构体中,然后将结构体写入一个文件。

但是,当我第二次重新分配内存时,它似乎无缘无故地失败了。此外,如果我输入超过 1 个人的信息,程序最终会因 seg 错误而失败。如果我只输入 1 个人的信息,程序运行良好。

谢谢。

// Program 

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

typedef struct person person;

struct person {
char fname[20];
char lname[20];
int num;
};

int main(void){
int size = 0;
int count = 0;
person* listofperson = NULL;
char answer = 'n';
FILE* myfile;

do{
    char* buf = (char*)malloc(sizeof(char)*50);
    printf("Please enter the person's first name: \n");
    fgets(buf, 50, stdin);
    if(count == size){
        size += 2;
        listofperson = (person*)realloc(listofperson, (size_t)(sizeof(person)*size));
    }
    strncpy((listofperson+count)->fname, buf, 50);
    printf("Please enter the person's last name: \n");
    fgets(buf, 50, stdin);
    strncpy((listofperson+count)->lname, buf, 50);
    printf("Please enter the person's number: \n");
    fgets(buf, 50, stdin);
    sscanf(buf, "%d", &((listofperson+count)->num));
    free(buf);
    count++;
    printf("Do you want to enter another one?\n");
    answer = getchar();
    getchar();
}while(tolower(answer) != 'n');

myfile = fopen("myfile", "a");
for(int i = 0; i < count; i++){
    fprintf(myfile, "%s", (listofperson+i)->fname );
    fprintf(myfile, "%s", (listofperson+i)->lname );
    fprintf(myfile, "%d\n", (listofperson+i)->num );
}
fclose(myfile);
myfile = NULL;
free(listofperson);
}

【问题讨论】:

  • strncpy((listofperson+count)-&gt;lname, buf, 50); 但你的数组大小是20
  • 如果没有先在传递给它的指针上调用malloc(),就不能调用realloc()
  • 如果你将一个空指针传递给 realloc,它就像 malloc 一样工作。见here

标签: c segmentation-fault realloc


【解决方案1】:

一方面,那些说 realloc() 不适用于 NULL 指针的人并没有说实话。该行为记录在 C++ 的 here 和 C 的 here 中,在传递 NULL 指针的情况下,它就像 malloc() 一样工作。虽然我同意以这种方式分配内存是不好的做法。

您没有检查 malloc() 和 realloc() 调用中的错误,它们不能保证成功,因此您不应该假设它们会成功。

在这种情况下,您不应该将您的点命名为人员节点“人员列表”,因为此约定可能与链接列表混淆。我强烈建议您尝试为此编程案例实现链接列表,因为这基本上就是您处理数据的方式。有关链表的教程,请参阅link

您应该在 fopen() 中更改文件名以包含 .txt 扩展名。否则系统将不知道文件类型是什么。

【讨论】:

  • 我不明白,我之所以没有使用括号表示法是因为我没有使用数组。我使用了指针。
  • 我在您发表评论之前对其进行了编辑,我忘记了在 C 中它会计算到正确的地址,我正在考虑添加字节。尽管如此,数组表示法更加清晰,并且对于指针仍然有效,所以我强烈建议使用它。请记住,数组与指针基本相同,但有一些注意事项。
  • 好的,但我还是不明白为什么 realloc 第二次失败了,为什么释放我的指针会导致分段错误。
  • 它对我来说只需几个快速更改,通过使用调试器并听取 cmet 中有关缓冲区溢出的建议,答案应该很简单。
【解决方案2】:

改变

struct person {
    char fname[20];
    char lname[20];
    int num;
};

struct person {
    char fname[50];
    char lname[50];
    int num;
};

这太小了,已经被ouah指出了。需要对齐一个的值。

错误信息表明内存被破坏超出了安全区域。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-25
    • 2012-10-31
    • 2013-09-28
    • 1970-01-01
    • 1970-01-01
    • 2015-04-12
    • 2016-01-02
    • 2018-06-13
    相关资源
    最近更新 更多