C语言链式链表从文件读取数据插入后显示无限循环的问题排查求助
链表读取文件后无限循环的问题排查与修复
问题回顾
你尝试用GetFile函数从record.txt读取数据插入链式链表,但调用display函数时出现无限循环,不确定问题出在SaveFile、GetFile还是display中。
核心问题:GetFile函数的内存分配逻辑错误
我仔细检查了你的代码,发现问题完全出在GetFile函数里:
你只在循环外部执行了一次malloc申请节点内存,然后在循环里反复修改这个节点的内容并插入链表:
struct Repertoire * rep = (struct Repertoire *) malloc(sizeof(struct Repertoire)); while(fscanf(ptr,"%s %s %s %s %s %s\n",phone,name,lastname,adresse,date,email)!=EOF){ // 始终修改同一个rep节点的内容 strcpy(rep->phone, phone); // ... 其他复制操作 // 反复将同一个节点插到链表头部 rep->next = head; head = rep; }
这会导致:
- 所有链表节点实际上都是同一个内存地址,新数据会覆盖旧数据
- 最后一次插入时,
rep->next = head,而此时head就是rep本身,形成了自引用的循环链表 - 循环结束后你调用
free(rep),还会把链表的头节点释放,造成野指针风险
这就是display函数遍历链表时无限循环的根本原因。
修复方案
把malloc放到循环内部,每次读取一行数据就创建一个新的独立节点。另外,你已经写了现成的insert函数,完全可以复用它来减少代码冗余:
修改后的GetFile函数:
void GetFile(){ char phone[10]; char name[100]; char lastname[100]; char adresse[100]; char date[100]; char email[100]; FILE *ptr = fopen("record.txt","r"); // 必须检查文件是否成功打开,避免空指针访问 if(ptr == NULL){ printf("Failed to open record.txt!\n"); return; } // 每次循环创建新节点,复用insert函数完成插入 while(fscanf(ptr,"%s %s %s %s %s %s",phone,name,lastname,adresse,date,email)!=EOF){ insert(phone, name, lastname, adresse, email, date); } printf("Data Imported Successfully !!"); import = 1 ; fclose(ptr); }
额外优化建议
- 文件操作安全检查:所有
fopen调用后都要判断返回值是否为NULL,你的SaveFile、insertFile函数也应该加上这个判断,避免程序崩溃。 - 移除fscanf的换行符:
%s格式符会自动跳过空白字符(包括换行),fscanf里的\n是多余的,可能导致读取异常。 - 添加链表内存释放函数:为了避免内存泄漏,建议写一个
freeList函数遍历链表,释放每个节点的内存:
void freeList() { struct Repertoire *temp, *nextNode; temp = head; while(temp != NULL) { nextNode = temp->next; free(temp); temp = nextNode; } head = NULL; }
验证修复
修改后,每次读取一行数据都会创建一个独立的节点,链表的每个next指针都会指向正确的下一个节点,display函数遍历到链表尾部(temp == NULL)时就会正常终止循环。
内容的提问来源于stack exchange,提问作者Oussama Chaieb
相关产品推荐
相关产品推荐

