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

两种指针传参方式一触发段错误一正常,差异何在?

为什么两种指针传参方式结果不同?

这是个非常典型的C语言指针层级和参数传递问题,我来给你拆解清楚:

先看第一种出错的写法

double ****A;
my_function(A);

这里你声明了一个四级指针变量A,但注意:你只是声明了它,完全没有给它初始化——也就是说A现在是个野指针,里面存的是随机的内存地址。

当你把A传给my_function时,C语言是值传递:函数会拿到A当前值的一个副本。如果my_function内部尝试对这个指针做解引用操作(比如*A = malloc(...)),本质是在访问那个随机的无效内存地址,直接触发段错误完全是意料之中的事。

再看第二种正常运行的写法

double ***A;
my_function(&A);

这里的A是三级指针变量,&A取的是这个变量在栈上的有效内存地址——而这个地址的类型正好是double****(和第一种写法里A的类型一致)。

这时候传给my_function的是一个完全合法的内存地址:指向栈上的A变量。函数内部如果做*A = malloc(...),本质是修改栈上A变量的值,让它指向一块你分配的堆内存,这完全是合法操作,自然不会触发段错误。

核心逻辑:C语言的「值传递」特性

这个问题的本质和修改普通变量的逻辑一模一样,只是多了几层指针:

  • 如果你想让函数修改一个int变量的值,不能直接传变量本身,得传它的地址(int*)
  • 同理,如果你想让函数修改一个double***变量的指向,就得传它的地址(也就是double****)

举个简化版的例子帮你理解:

// 错误:传值,修改的是副本,外部变量不受影响
void set_int_wrong(int x) { x = 42; }
int num = 0;
set_int_wrong(num); // num还是0

// 正确:传地址,修改的是外部变量本身
void set_int_right(int *x) { *x = 42; }
int num = 0;
set_int_right(&num); // num变成42

你的指针传参问题就是这个逻辑的多层延伸,只是把int换成了double***而已。

总结一下

  • 第一种写法里的A是未初始化的野指针,传递给函数后操作的是无效内存
  • 第二种写法传递的是有效变量的地址,函数可以合法修改外部指针的指向
  • 关键要记住:C语言所有参数都是值传递,要修改外部变量(包括指针变量),必须传递它的地址

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.28 09:32:36