链表中char*类型字段数据被覆盖问题的技术咨询
解决链表中char*字段被后续输入覆盖的问题
嘿,这个问题我太熟了!你这是踩了C语言指针和内存管理的经典坑——所有链表节点的data指针都指向了同一块内存区域,每次输入新字符串都会覆盖这块内存的内容,自然所有节点最后显示的都是最后输入的内容。
先看看你大概率写错的代码示例
你可能是像下面这样写的:
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Node { char* data; struct Node* next; } Node; Node* createNode(char* input) { Node* newNode = (Node*)malloc(sizeof(Node)); // 错误核心:直接把输入缓冲区的指针赋值给data newNode->data = input; newNode->next = NULL; return newNode; } int main() { Node* head = NULL; char buf[50]; // 所有输入都存在这个栈缓冲区里 for (int i = 0; i < 3; i++) { printf("输入姓名:"); scanf("%s", buf); Node* newNode = createNode(buf); // 头插法添加节点 newNode->next = head; head = newNode; } // 遍历链表 Node* p = head; while (p != NULL) { printf("%s ", p->data); p = p->next; } return 0; }
运行这段代码的话,你会发现最后输出的全是第三次输入的字符串——因为三个节点的
data都指向了buf数组的地址,每次输入都会覆盖buf里的内容,所有节点自然跟着变。
正确的解决思路:给每个节点分配独立的字符串内存
我们需要为每个节点的data单独在堆上申请内存,把输入的字符串拷贝进去,而不是直接复用同一个缓冲区的指针。
方法一:用strdup快速实现(最省心)
strdup函数会自动计算字符串长度、分配足够的堆内存,然后把字符串拷贝进去,非常方便:
Node* createNode(char* input) { Node* newNode = (Node*)malloc(sizeof(Node)); if (newNode == NULL) return NULL; // 分配内存并拷贝字符串 newNode->data = strdup(input); newNode->next = NULL; // 检查内存分配是否成功 if (newNode->data == NULL) { free(newNode); return NULL; } return newNode; }
方法二:手动用malloc+strcpy实现(兼容性更强)
如果你的环境不支持strdup(比如某些嵌入式场景),可以手动分配内存再拷贝:
Node* createNode(char* input) { Node* newNode = (Node*)malloc(sizeof(Node)); if (newNode == NULL) return NULL; // 计算字符串长度+1(要存字符串结束符'\0') int strLen = strlen(input) + 1; newNode->data = (char*)malloc(strLen); if (newNode->data == NULL) { // 内存分配失败,要先释放节点内存,避免内存泄漏 free(newNode); return NULL; } // 把输入字符串拷贝到新分配的内存里 strcpy(newNode->data, input); newNode->next = NULL; return newNode; }
最后别忘了清理内存!
链表使用完后,一定要记得逐个节点释放内存,先释放data指向的字符串内存,再释放节点本身:
void freeLinkedList(Node* head) { Node* tempNode; while (head != NULL) { tempNode = head; head = head->next; // 先释放字符串内存 free(tempNode->data); // 再释放节点本身 free(tempNode); } }
内容的提问来源于stack exchange,提问作者yijie yan
相关产品推荐
相关产品推荐

