在Eclipse Luna中使用链表写入文件时出现垃圾数据问题求助
问题排查与代码修正
嗨,我来帮你梳理下代码里的问题——你的printf输出正常但文件写入垃圾数据,核心是几个逻辑和用法错误,咱们一步步拆解:
1. fwrite 参数完全用错了
你写的这行:
ret= fwrite((struct DETAIL *)&(ptr->next),1,sizeof(struct DETAIL),fp));
首先有个语法错误——多了一个右括号 ),不过你说printf正常,可能是输入时的手误。但最致命的是:&(ptr->next) 取的是指针变量ptr->next自己的地址,而不是你要写入的结构体的地址。ptr->next本身是一个指向struct DETAIL的指针,你把这个指针的地址传给fwrite,写入的其实是这个指针的内存地址值(也就是stTmp的地址),根本不是结构体里的data和next数据,这肯定是你看到的“垃圾数据”。
2. 所有链表节点都指向同一块内存
你只malloc了一次stTmp,循环里每次只是修改它的data,然后让ptr->next指向它。这意味着你所谓的“10条记录”其实全是同一个结构体实例,最后链表的所有节点都指向同一块内存,就算写入逻辑对了,也只会重复写入同一个内容。
3. 链表初始化逻辑混乱
你一开始malloc了ptr,但这个初始的ptr既没初始化data也没处理next,直接让ptr->next = stTmp,循环里ptr = ptr->next,最后ptr会一直指向stTmp,根本没构建出真正的10个节点的链表。
修正后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> struct DETAIL { char data[12+1]; struct DETAIL* next; }; int main() { int ret = 0; FILE *fp = fopen("linked","w+"); if (fp == NULL) { // 务必检查文件是否打开成功 perror("Failed to open file"); return 1; } struct DETAIL *head = NULL; // 链表头节点,用于后续内存释放 struct DETAIL *current = NULL; int i = 0; for(i = 0; i<10; i++) { // 每次循环都为新节点分配内存 struct DETAIL *stTmp = (struct DETAIL*)malloc(sizeof(struct DETAIL)); if (stTmp == NULL) { perror("Failed to allocate memory"); // 这里可以加入已分配内存的清理逻辑,避免泄漏 return 1; } sprintf(stTmp->data,"%012d",i+1); stTmp->next = NULL; // 初始化next指针为NULL,避免野指针 // 构建链表:第一次循环初始化头节点,后续追加新节点 if (head == NULL) { head = stTmp; current = stTmp; } else { current->next = stTmp; current = stTmp; } // 正确写入结构体数据到文件:直接传结构体指针 ret = fwrite(stTmp, sizeof(struct DETAIL), 1, fp); if (ret != 1) { printf("Write failed for record %d\n", i+1); } printf("data[%d]:%s\n",i,stTmp->data); } // 释放链表所有节点的内存,避免内存泄漏 struct DETAIL *tmp = head; while (tmp != NULL) { struct DETAIL *nextNode = tmp->next; free(tmp); tmp = nextNode; } fclose(fp); // 关闭文件,确保数据写入磁盘 return 0; }
关键知识点梳理
fwrite的正确用法:第一个参数是要写入的数据的起始地址,如果你要写入整个结构体,直接传结构体指针(比如stTmp)即可,而不是指针的地址。另外fwrite的参数顺序是(数据地址, 单个元素大小, 元素个数, 文件指针),我调整成sizeof(struct DETAIL), 1,这样更清晰表示“写入1个大小为结构体的元素”,和你原来的1, sizeof(...)功能一致,但可读性更好。- 链表节点的创建:每个节点必须单独分配内存,否则所有节点都会指向同一块内存,修改一个就会影响所有节点,根本存不下10条不同的记录。
- 资源清理:文件打开后一定要关闭(否则可能导致数据未写入磁盘),
malloc的内存一定要free,避免内存泄漏。 - 错误检查:文件打开、内存分配都要检查返回值,这是C语言编程的良好习惯,能帮你快速定位很多隐藏问题。
内容的提问来源于stack exchange,提问作者Chandra Mani
相关产品推荐
相关产品推荐

