C语言控制台链表程序添加节点时名称被覆盖问题求助
C语言链表添加用户输入节点时名称共享的问题解决
问题根源
你遇到的问题核心在于所有用户输入添加的节点都共享了同一个内存地址的指针:
main.c中的uInput是静态字符数组,每次输入新名称都会覆盖数组内的内容addLast函数里直接执行node->name = name,这里的name是uInput的指针,导致所有新添加节点的name成员都指向uInput的起始地址。当后续输入覆盖uInput时,所有节点的name显示的自然都是最后一次输入的内容。- 初始化时的
"joe"、"james"这类字符串字面量存储在只读数据段,不会被覆盖,所以这部分节点显示正常。
解决方案
要为每个节点的name分配独立的内存空间,复制输入的字符串,而不是直接复用指针。可以用strdup函数(简化版)或手动malloc+strcpy实现。
步骤1:添加必要头文件
在list.h顶部添加字符串操作的头文件:
#include <string.h>
步骤2:修改addLast函数的字符串赋值逻辑
把直接赋值指针的代码替换为字符串复制:
void addLast(node_js **thing, const char *name, int val) { if (*thing == NULL) { *thing = (node_js *)malloc(sizeof(node_js)); // 替换原指针赋值为字符串复制 (*thing)->name = strdup(name); (*thing)->value = val; (*thing)->next = NULL; } else { currentNode = *thing; while (currentNode->next != NULL) { currentNode = currentNode->next; } currentNode->next = (node_js *)malloc(sizeof(node_js)); // 同样替换为字符串复制 currentNode->next->name = strdup(name); currentNode->next->value = val; currentNode->next->next = NULL; } }
如果不想用strdup(部分环境可能不支持),可以手动分配内存:
// 替换strdup的写法 (*thing)->name = malloc(strlen(name) + 1); strcpy((*thing)->name, name);
步骤3:修复内存泄漏
现在每个节点的name都分配了独立内存,删除节点时需要先释放name再释放节点,修改removeLast函数:
void removeLast(node_js **thing) { if (*thing == NULL) { return; } if ((*thing)->next == NULL) { // 先释放name内存 free((*thing)->name); free(*thing); *thing = NULL; return; } currentNode = *thing; while (currentNode->next->next != NULL) { currentNode = currentNode->next; } // 先释放最后一个节点的name内存 free(currentNode->next->name); free(currentNode->next); currentNode->next = NULL; }
额外优化
main.c中初始化链表的代码可以统一用addLast函数,避免手动malloc的冗余:
// 替换原手动初始化链表的代码 list = NULL; addLast(&list, "joe", 10); addLast(&list, "james", 20); addLast(&list, "jane", 30);
说明
你之前注释掉的//currentNode->next->name = strdup(name);其实是正确的解决方向,只是没启用,也没处理对应的头文件和内存释放逻辑,导致问题没解决。
内容的提问来源于stack exchange,提问作者danilogames220
相关产品推荐
相关产品推荐

