You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何这段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;
}

修改说明

  1. 指针的指针传参:将read函数的参数改为struct node** head,使函数内部能直接修改main中head的指向,确保链表头节点能正确传递回去。
  2. 移除冗余内存分配:main中将head初始化为NULL,不再提前分配内存;read函数开头删除了无用的cur内存分配。
  3. 添加错误处理:检查fopen和malloc的返回值,避免空指针操作导致程序崩溃。
  4. 优化代码规范:去掉malloc的强制转换(C语言中无需强制转换),调整代码格式提升可读性,同时添加内存释放代码避免内存泄漏。

内容的提问来源于stack exchange,提问作者user20470572

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.06 04:16:07