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

C++中如何使用指针获取第一个数组紧邻的下一个数组的地址

差异产生的核心原因

  1. 首先明确C/C++的指针运算通用规则:对任意类型指针T* p执行p + 1操作,实际偏移的字节数等于sizeof(T)。对数组名取地址&arr得到的是指向整个数组的指针,对应类型为T (*)[N](T为数组元素类型,N为数组总长度),因此&arr + 1的偏移量等于sizeof(arr),也就是整个数组占用的总字节数。该规则对一维、二维数组完全统一,本身不存在差异。
  2. 你观察到的一维、二维场景下的结果差异,本质和数组维度无关,是栈上局部变量的内存排布规则导致的:
    • C/C++标准从未规定栈上连续定义的局部变量的内存地址顺序,也不保证相邻定义的同类型变量之间没有填充字节。编译器会根据内存对齐要求、编译优化等级、栈保护机制等因素,自主调整变量的排布,甚至在变量之间插入填充字节。
    • 栈的默认增长方向是从高地址向低地址,也就是说先定义的局部变量通常地址更高,后定义的更低,所以&a+1得到的是a数组后方的高地址,而后定义的b数组通常分配在a数组前方的低地址,二者本来就不必然相等。
    • 二维数组场景下&a+1刚好等于&b,只是当前编译环境下的巧合:编译器刚好把b数组放在a数组的高地址方向,且中间没有插入填充,这种情况不具备可移植性,换编译参数或编译器就可能失效。
    • 一维数组场景下两个地址不一致,才是更符合栈排布规则的常见情况。

正确的实现方案

首先需要明确:如果你操作的是同一个数组内的元素或子数组,直接用标准指针算术即可,比如二维数组a的第i个一维子数组地址可以直接用a + i获取,结果完全可靠。
如果你确实需要保证两个数组的地址相对固定,有两种可移植的实现方案:

方案1:将数组封装到结构体中

C标准保证结构体成员的地址按定义顺序递增,仅在成员之间插入满足对齐要求的最少填充,因此可以得到固定的相对偏移:

struct ArrGroup {
    int A[5];
    int B[5];
};
// 此时B相对于A的偏移量固定为 &(((ArrGroup*)0)->B)

方案2:合并为更大的数组

从根源上保证内存连续,完全符合C标准要求:

// 两个一维数组合并为二维数组
int AB[2][5] = {{1,2,3,4,5}, {1,2,3,4,5}};
// AB[0]对应原A数组,AB[1]对应原B数组,AB + 1 就是B数组的地址,100%可靠

禁止直接依赖栈上独立变量的相对地址,这种写法没有可移植性,修改优化等级、更换编译器、开启栈保护都会导致结果异常。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.03 08:06:03