You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言链表头插法传一级指针的push函数为何失效?

C语言链表头插函数传参失效问题解析

问题本质

失效的核心原因是C语言所有函数参数均为值传递:函数调用时实参会被拷贝为函数内部的独立局部变量,函数内对局部形参的修改不会同步到外部的原始实参。


可正常运行的参考实现

#include <stdio.h>
#include <stdlib.h>

typedef struct node {
  int val;
  struct node *next;
} node_t;

void push(node_t **head, int val) {
  // head是指向「链表首节点指针」的二级指针
  node_t *new_node = (node_t *)malloc(sizeof(node_t));
  new_node->val = val;
  new_node->next = *head;
  *head = new_node;
}

int main() {
  // 初始化第一个节点
  node_t *head = (node_t *)malloc(sizeof(node_t));
  head->val = 2;
  head->next = NULL;
  
  // 头插新节点,必须传入head的地址
  push(&head, 1);

  return 0;
}

这个版本调用push时传入&head,也就是main函数中原始首节点指针的内存地址,函数内通过二级指针解引用可以直接修改外部原始指针的指向,因此头插逻辑生效。


修改后版本的失效原因

你修改后的函数实现如下:

void push(node_t *head, int val) {
  node_t **p_head;
  p_head = &head; // 这里取到的是局部形参的地址,不是外部原始head的地址

  node_t *new_node = (node_t *)malloc(sizeof(node_t));
  new_node->val = val;
  new_node->next = *p_head;
  *p_head = new_node;
}

执行时的问题链路非常明确:

  • 调用push(head, 1)时,main里的原始head指针(指向val=2的首节点)会被拷贝一份,赋值给push函数内部的局部形参head,这是两个完全独立的指针变量,只是初始保存的地址值相同
  • 函数内p_head = &head拿到的是push内部局部形参head的地址,和main里的原始head没有任何关系
  • 后续*p_head = new_node修改的只是push内部局部形参的指向,等函数执行结束,局部变量全部销毁,main里的原始head还是指向原来的首节点,新创建的节点因为没有任何有效指针指向,还会造成内存泄漏。

可以用一个通俗的类比理解:你想让外卖员把餐送到你家,正确做法是给外卖员你家的真实地址(传&head,二级指针),外卖员能直接找到你家;如果你只是把你家的门牌号抄在一张纸条上给外卖员,外卖员在纸条上改个别的门牌号,永远也找不到你真正的家。


内容的提问来源于stack exchange,提问作者Jaime

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 02:12:32