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

在C语言中,将数组指针传递为指针的指针属于未定义行为吗?

这段C代码的未定义行为分析

首先明确:这段代码确实存在未定义行为(UB),核心原因就是你指出的类型不匹配:

  • func的参数类型是int **(指向int指针的指针),但调用时传入的&b是int (*)[10]类型(指向包含10个int的数组的指针),二者属于完全不同的指针类型,C标准不允许这种隐式的跨类型指针转换,后续通过错误类型的指针访问内存的操作更是典型的UB。

为什么会出现当前的输出结果?

这只是编译器实现的巧合,不能代表标准行为:

  1. 数组的首地址和数组自身的地址,在数值上是相同的(比如你的输出中都是0x7ffe76932330),所以printf打印出的地址值一致。
  2. 当把int (*)[10]类型的地址隐式转换成int **后,func里的*b会把这个地址当成int*来解引用——也就是读取该地址处的4字节内容,而这个地址正好是数组第一个元素b[0]的内存位置,初始值为0。
  3. *b = *b + 1是指针算术操作:*b作为int*类型,+1会让指针向后移动一个int的长度(通常是4字节),指向b[1]的地址;随后将这个新地址赋值给*b,也就是把该地址写入b[0]的内存中。
  4. 最后printf("%d\n", b[0])读取的是b[0]内存里的地址值,取低4字节就得到了4(因为b[1]的地址比b[0]大4)。

但这种结果完全是平台和编译器的特定实现,换个环境可能出现崩溃、乱码或其他完全不同的输出,没有任何可移植性。

改成char b[] = "some string"后行为类似的原因

原理和int数组的情况一致:

  • char数组的首地址和数组自身地址数值相同,传入&b到对应char**类型的参数时,同样是类型不匹配的UB。
  • 因为char的大小是1字节,*b +1会让指针向后移动1字节,赋值给*b后,数组首元素的内存被改成下一个元素的地址,输出时读取到的是该地址的低字节,看起来和int数组的“偏移后数值变化”表现类似,但本质依然是未定义行为,完全依赖编译器的内存布局实现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 13:00:28