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

C++数组指针运算的未定义行为:为何程序输出结果为4?

为什么这段C++代码的输出是4而不是预期的0x0500?

嘿,我来帮你拆解这个问题!你对内存布局的理解基本正确,但忽略了两个核心点——未定义行为的影响和不对齐指针访问的实际处理逻辑。

1. 先明确数组的内存布局(你的理解是对的)

在x86小端系统中,short占2字节,低位字节存在低地址,高位字节在高地址。所以数组A[] = {1,2,3,4,5,6}的十六进制存储确实是:

地址偏移: 0  1  2  3  4  5  6  7  8  9  10 11
字节内容: 01 00 02 00 03 00 04 00 05 00 06 00
对应元素: A[0]   A[1]   A[2]   A[3]   A[4]   A[5]

其中A[3] = 4对应的是偏移6(04)和偏移7(00)的两个字节,小端组合后就是0x0004,也就是十进制的4。

2. 你的理解偏差在哪里?

你认为(char*)A +7偏移后读取2字节会得到0x0500,是假设从偏移7的位置(字节00)开始,读取偏移7和8的两个字节(00和05),组合成0x0500。但实际输出是4,说明程序读取的是偏移6和7的字节(04和00)——这正是A[3]的值。

3. 问题的核心:未定义行为的影响

这段代码存在C++标准明确规定的未定义行为:将一个不对齐的char*指针强制转换为short*指针并解引用。

short类型在x86系统上要求2字节对齐(地址必须是偶数),而(char*)A +7得到的是奇数地址(偏移7),不符合short的对齐要求。对于这种未定义行为,C++标准不保证任何特定结果,不同编译器、优化级别甚至CPU架构都可能产生不同的输出:

  • 在你的测试环境中,编译器或CPU可能自动将不对齐的short*地址对齐到了最近的偶数地址(也就是偏移6的位置),因此解引用时读取了A[3]的两个字节,输出4。
  • 在其他环境中,可能会按你预期的读取偏移7和8的字节,输出1280(0x0500);甚至可能出现程序崩溃、其他奇怪结果。

4. 验证一下

如果把代码改成*(short*)((char*)A +6)(偏移6,偶数地址,符合对齐要求),那输出必然是4,这是符合标准的行为。而偏移7的情况完全是未定义的,你的预期和实际输出的差异正是这种未定义行为的体现。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.20 10:31:02