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

从文件读取数据到链表时出现无限循环问题求助

链表读写文件后无限循环的问题分析与修复

你的代码存在几个关键问题,直接导致了打印时的无限循环,下面逐个拆解并给出修复方案:

1. 读取文件时重复复用同一块节点内存

read_from_file函数里只malloc了一个temp结构体,每次fread都是把文件内容覆盖到这块内存里,再把它加到链表中。这就导致链表的所有节点其实都是指向同一块内存的指针,最终形成循环链表,打印时自然会无限循环。

2. 写入文件时错误保存了无效指针

write_to_file用fwrite直接把整个struct Program写入文件,其中包含的next指针是程序运行时的内存地址,写入文件后完全无效,读取时会读到垃圾值,进一步破坏链表结构。

3. 其他潜在问题

  • addProgram函数先malloc了temp,随后又把inputProgram返回的指针赋值给它,导致第一次malloc的内存泄漏;同时函数返回temp而非head,会导致链表头丢失。
  • read_from_file里的head未初始化,属于野指针,第一次判断head == NULL的行为未定义。

修正后的完整代码

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

struct Program {
    char p_name[50];
    char p_code[10];
    char responsible[50];
    char r_email[50];
    struct Program* next;
};

struct Program* inputProgram() {
    struct Program *temp = (struct Program*)malloc(sizeof(struct Program));
    printf("Enter the name of program: \n");
    scanf("%s", temp->p_name);
    printf("Enter the code of program: \n");
    scanf("%s", temp->p_code);
    printf("Enter the responsible of program: \n");
    scanf("%s", temp->responsible);
    printf("Enter the email of responsible: \n");
    scanf("%s", temp->r_email);
    temp->next = NULL; // 初始化next为NULL,避免垃圾值
    return temp;
}

struct Program* addProgram(struct Program* head) {
    struct Program *temp = inputProgram(); // 直接复用inputProgram的节点,避免内存泄漏
    if (head == NULL) {
        head = temp;
    } else {
        temp->next = head;
        head = temp;
    }
    return head; // 返回正确的链表头
}

void write_to_file(struct Program* p) {
    FILE *of = fopen("program.txt", "w");
    if (!of) { // 增加文件打开失败判断
        perror("Failed to open file for writing");
        return;
    }
    struct Program* temp = p;
    while(temp != NULL) {
        // 只写入数据字段,跳过无效的next指针
        fwrite(temp->p_name, sizeof(temp->p_name), 1, of);
        fwrite(temp->p_code, sizeof(temp->p_code), 1, of);
        fwrite(temp->responsible, sizeof(temp->responsible), 1, of);
        fwrite(temp->r_email, sizeof(temp->r_email), 1, of);
        temp = temp->next;
    }
    fclose(of);
}

struct Program* read_from_file() {
    FILE *in = fopen("program.txt", "r");
    if (!in) { // 增加文件打开失败判断
        perror("Failed to open file for reading");
        return NULL;
    }
    struct Program* head = NULL;
    struct Program* tail = NULL; // 用尾插法构建链表,逻辑更直观
    while(1) {
        struct Program* temp = (struct Program*)malloc(sizeof(struct Program));
        // 逐个读取数据字段
        size_t read_count = fread(temp->p_name, sizeof(temp->p_name), 1, in);
        if (read_count != 1) {
            free(temp); // 读取失败时释放当前节点
            break;
        }
        fread(temp->p_code, sizeof(temp->p_code), 1, in);
        fread(temp->responsible, sizeof(temp->responsible), 1, in);
        fread(temp->r_email, sizeof(temp->r_email), 1, in);
        temp->next = NULL; // 手动初始化next为NULL
        
        if (head == NULL) {
            head = temp;
            tail = temp;
        } else {
            tail->next = temp;
            tail = temp;
        }
    }
    fclose(in);
    return head;
}

int main() {
    struct Program *head = NULL;
    head = addProgram(head);
    head = addProgram(head);
    write_to_file(head);
    struct Program *temp = read_from_file();
    while(temp != NULL){
        printf("%s\n", temp->p_name); // 增加换行,方便查看输出
        temp = temp->next;   
    }
    // 释放链表内存,避免内存泄漏
    temp = head;
    while(temp != NULL){
        struct Program* next = temp->next;
        free(temp);
        temp = next;
    }
    temp = read_from_file();
    while(temp != NULL){
        struct Program* next = temp->next;
        free(temp);
        temp = next;
    }
    return 0;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 03:07:58