分段错误和realloc():下一个大小无效:

时间:2014-02-21 23:17:50

标签: c segmentation-fault realloc

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

然而,当我第二次重新分配内存时,似乎没有任何理由失败。此外,如果我输入超过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);
}

2 个答案:

答案 0 :(得分:2)

首先,那些说realloc()不能使用NULL指针的人并不是说实话。对于C ++,行为被记录为here,对于C,行为被记录为here,在传递NULL指针的情况下,它就像malloc()一样。虽然我同意以这种方式分配内存是不好的做法。

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

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

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

答案 1 :(得分:0)

更改

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

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

这个太小了,ouah已经指出了。有必要对齐一个值。

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