C语言链表实现触发程序终止,函数外修改首节点数据失效原因咨询
问题原因
- C语言函数参数默认采用值传递规则:你向
add_node传入的head是main函数中头指针的副本,函数内部对形参head执行head = new_node的赋值操作,仅作用于函数内部的局部副本,不会修改main函数中原始head变量的值。执行完add_node调用后,main里的head仍然是NULL,后续执行head->data = 2属于空指针访问,直接触发程序崩溃。 - 函数返回值未被接收:
add_node中已经将新建节点的指针作为返回值返回,但main函数调用时没有接收该返回值,不仅导致新节点的地址丢失造成内存泄漏,也没有获取到新建节点的合法访问入口。 - 你观察到的「函数内部可以正常给首节点赋值」是正常现象:
add_node内部的形参head已经指向了malloc出来的合法堆内存,操作当然有效,只是这个修改没有同步到函数外部的head变量,才导致外部操作失效。
修复方案
方案1:接收函数返回值
直接修改main函数中add_node的调用逻辑,用原head变量接收返回的新节点地址即可:
#include <stdlib.h> #include <stdio.h> struct node { int data; struct node *link; }; struct node *add_node(struct node *head, struct node *tail); int main() { struct node *head = NULL, *tail = NULL; // 改动点:用head接收返回的新节点地址 head = add_node(head, tail); head->data = 2; // 测试输出正常 printf("%d", head->data); // 记得释放堆内存避免泄漏 free(head); return 0; } struct node *add_node(struct node *head, struct node *tail) { if (head == NULL) { struct node *new_node = (struct node *) malloc(sizeof(struct node)); head = new_node; return new_node; } // 非空链表的添加逻辑你可以后续补充 return head; }
方案2:使用二级指针传参
如果你希望直接在函数内部修改外部指针的原值,不需要依赖返回值传递,可以传入指针的地址(二级指针),修改示例如下:
// 函数声明改为接收二级指针 void add_node(struct node **head, struct node **tail); int main() { struct node *head = NULL, *tail = NULL; // 传入head的地址 add_node(&head, &tail); head->data = 2; printf("%d", head->data); free(head); return 0; } void add_node(struct node **head, struct node **tail) { if (*head == NULL) { struct node *new_node = (struct node *) malloc(sizeof(struct node)); // 直接修改外部head变量的值 *head = new_node; *tail = new_node; return; } // 非空链表添加逻辑后续补充 }
内容的提问来源于stack exchange,提问作者programmerc3981143
相关产品推荐
相关产品推荐

