从文件读取数据到链表时出现无限循环问题求助
链表读写文件后无限循环的问题分析与修复
你的代码存在几个关键问题,直接导致了打印时的无限循环,下面逐个拆解并给出修复方案:
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
相关产品推荐
相关产品推荐

