C语言链表中fgets()覆盖结构体部分数据的问题求助
C语言链表学生信息被覆盖的问题解决
问题根因
你这问题说白了就是所有链表节点的字符串都共用了同一块内存。比如你可能定义了一个全局或者局部的字符数组当输入缓冲区,然后直接把这个数组的地址塞给结构体里的字符串指针,没给每个节点单独开内存存自己的字符串。这样每次调用fgets()往缓冲区里写新内容,之前节点存的指针指向的还是这块缓冲区,自然就被覆盖了。
解决办法
给每个节点的字符串单独分配内存
读入学生信息后,别直接把缓冲区地址赋值给结构体,用malloc申请一块新内存,再把缓冲区里的内容复制过去:// 拿姓名字段举例子 char input_buf[100]; fgets(input_buf, sizeof(input_buf), stdin); // 先去掉fgets自带的换行符 input_buf[strcspn(input_buf, "\n")] = '\0'; // 申请内存,长度要包含字符串结束符'\0' new_node->name = malloc(strlen(input_buf) + 1); if (new_node->name == NULL) { // 内存分配失败的处理,比如报错退出 perror("内存分配失败"); exit(1); } // 把缓冲区内容复制到新内存里 strcpy(new_node->name, input_buf);别犯直接赋值指针的低级错误
绝对不能这么写:new_node->name = input_buf; // 大错!所有节点的name都指向同一个input_buf这种写法等于所有节点的字符串都指着同一段内存,后面输入的内容必然覆盖前面的。
验证修改效果
改完可以打印每个节点字符串的内存地址(printf("%p\n", node->name);),每个节点的地址应该不一样,要是都一样说明还没改对。
额外提醒
- 销毁链表的时候,要先释放每个节点里的字符串内存,再释放节点本身,不然会出现内存泄漏。
fgets()会把换行符读进缓冲区,记得用strcspn()去掉,不然存的字符串里会带换行符,显示时容易出问题。
内容的提问来源于stack exchange,提问作者Caleb Barone
相关产品推荐
相关产品推荐

