为啥一个接一个声明的两个变量在内存中不相邻?

Posted

技术标签:

【中文标题】为啥一个接一个声明的两个变量在内存中不相邻?【英文标题】:Why two variables declared one after another are not next to each other in memory?为什么一个接一个声明的两个变量在内存中不相邻? 【发布时间】:2019-10-15 18:18:39 【问题描述】:

我正在使用代码示例来检查两个整数之间的距离,例如 the answer of this question。

int i = 0, j = 0;
std::cout << &i - &j;

根据我对内存表示的理解,这两个变量的这些内存地址应该是相邻的,并且差应该正好是1。

令我惊讶的是,在 VS2017 中使用 MS 编译器运行此代码会打印出 3,而使用 GCC 运行相同的代码会打印出 1

为什么会出现这种情况,VS有什么问题吗?

【问题讨论】:

您所做的是未定义的行为。除非它们在同一个数组中,否则不能减去指针。 内存布局完全由编译器决定局部变量。只有类或结构成员才能获得标准的任何保证。 "根据我对内存表示的理解,这两个变量的这些内存地址应该是相邻的,并且差值应该正好是1。" 你从哪里得到的这样的理解,从何而来? @AlgirdasPreidžius 我对这个假设有点偏离,认为变量将一个接一个地放置在内存中,但你是对的,它们可以在任何地方。不过,我倾向于相信,在大多数情况下,它们会彼此靠近。 @meJustAndrew 这仍然没有回答我提出的问题:你从哪里得到这样的理解? “不过,我倾向于相信在大多数情况下,在这些情况下,它们会彼此接近。” 这些信念基于什么?你刚刚得到了一个结果,这与那些信念相矛盾.. 【参考方案1】:

C++ 标准不要求 C++ 编译器以任何特定方式分配具有自动存储持续时间的变量,包括使它们在内存中连续。事实上,编译器可能会选择不为变量分配任何内存,完全优化它。

这就是为什么减去指针只有在它们都指向同一个数组内的内存或超过数组末尾的一个元素时才有意义。在所有其他情况下,包括您的情况,您都会得到未定义的行为。

【讨论】:

【参考方案2】:

您尝试的指针arithmetic 具有未定义的行为:

如果指针 P 指向数组的第 i 个元素,并且 指针 Q 指向同一个数组的第 j 个元素, 如果值适合 std::ptrdiff_t,则表达式 P-Q 具有值 i-j。 两个操作数必须指向同一个数组的元素(或一个 结束),否则行为未定义。 如果结果是 不适合 std::ptrdiff_t,行为未定义。

【讨论】:

以上是关于为啥一个接一个声明的两个变量在内存中不相邻?的主要内容,如果未能解决你的问题,请参考以下文章

为啥在某些语言中使用变量之前需要声明变量,而在其他语言中则不需要? [关闭]

为啥要在 main 中声明一个静态变量?

为啥我可以在javascript中删除一个声明为a = 1的变量而不是一个声明的var b = 1 [重复]

声明一个公共变量会导致所有内容都具有“此上下文中不存在名称”错误[关闭]

为啥在嵌套函数之外声明一个计数器变量会使循环慢 5 倍?

GO语法