为何这段C语言代码无法将文件内容读取到链表中?
问题:链表读取文件数据后无限输出错误值
我无法理解这段代码的问题所在,它未输出正确结果。代码如下:
#include <stdio.h> #include <stdlib.h> struct node{ int data; struct node*next; }; void traversal(struct node*ptr){ while(ptr!=NULL){ printf("Element is: %d\n",ptr->data); ptr=ptr->next; } } void read(struct node*head){ FILE*file; int val; struct node*cur=(struct node*)malloc(sizeof(struct node)); head=cur=NULL; file=fopen("list.txt","r"); while(fscanf(file,"%d",&val)!=EOF){ struct node*ptr=(struct node*)malloc(sizeof(struct node)); ptr->data=val; ptr->next=NULL; if(head==NULL){ head=cur=ptr; } else{ cur=cur->next=ptr; } } fclose(file); } int main(){ struct node* head; //Allocate memory for linked list nodes in heap head=(struct node*)malloc(sizeof(struct node)); read(head); traversal(head); }文件内容为:
3 5 6 1 3程序输出无数行错误数值,陷入无限输出。
问题根源
- 参数传递错误:
read函数采用值传递,函数内部对head的修改不会影响main中的head指针。main中提前分配的head指向一块未初始化的内存,traversal遍历时读取的是垃圾值,且该内存的next指针不为NULL,直接导致无限循环。 - 冗余内存分配:
read函数开头为cur分配内存后立刻将其设为NULL,造成内存泄漏;main中提前为head分配的内存完全无用,反而引发后续的无限遍历问题。 - 缺少错误检查:若
list.txt不存在,fopen会返回NULL,后续fscanf会直接出错,但代码未做任何处理。
修改后的代码
#include <stdio.h> #include <stdlib.h> struct node{ int data; struct node* next; }; void traversal(struct node* ptr){ while(ptr != NULL){ printf("Element is: %d\n", ptr->data); ptr = ptr->next; } } // 使用指针的指针修改main中的head指针 void read(struct node** head){ FILE* file = fopen("list.txt", "r"); if(!file){ perror("Failed to open file"); return; } int val; struct node* cur = NULL; *head = NULL; while(fscanf(file, "%d", &val) != EOF){ struct node* ptr = malloc(sizeof(struct node)); if(!ptr){ perror("Failed to allocate memory"); fclose(file); return; } ptr->data = val; ptr->next = NULL; if(*head == NULL){ *head = cur = ptr; } else { cur->next = ptr; cur = ptr; } } fclose(file); } int main(){ struct node* head = NULL; read(&head); traversal(head); // 释放链表内存,避免泄漏 struct node* temp; while(head != NULL){ temp = head; head = head->next; free(temp); } return 0; }
修改说明
- 指针的指针传参:将
read函数的参数改为struct node** head,使函数内部能直接修改main中head的指向,确保链表头节点能正确传递回去。 - 移除冗余内存分配:
main中将head初始化为NULL,不再提前分配内存;read函数开头删除了无用的cur内存分配。 - 添加错误处理:检查
fopen和malloc的返回值,避免空指针操作导致程序崩溃。 - 优化代码规范:去掉
malloc的强制转换(C语言中无需强制转换),调整代码格式提升可读性,同时添加内存释放代码避免内存泄漏。
内容的提问来源于stack exchange,提问作者user20470572
相关产品推荐
相关产品推荐

