对于程序的不同运行,全局变量的地址是否相同?

时间:2014-07-25 09:37:50

标签: c++ virtual-memory

请考虑以下代码段

int i=10;
int main()
{
    cout<<&i;
}

一旦为程序生成了exe,对于程序的不同运行,输出是否相同?假设操作系统支持虚拟内存

编辑:问题特定于存储在数据段中的全局变量。由于这是第一个全局变量,地址应该是相同还是不同?

4 个答案:

答案 0 :(得分:3)

虚拟地址将是链接器决定的任何地址。 物理地址会随着每次加载而变化。

答案 1 :(得分:1)

如果ASLR被禁用,您将始终获得相同的地址。如果启用了ASLR,您将获得不可预测的地址。

答案 2 :(得分:0)

简单回答:这取决于: - )

如果您的操作系统启动的程序总是与虚拟内存范围相同的环境看起来始终相同,则输出应始终相同。

但是如果你在不同的硬件上运行相同的操作系统(可能有不同数量的ram),它可能会在不同的地址中被解析,但通常地址也是相同的,与硬件无关。

但你永远不要指望结果是一样的!简而言之:不要考虑你的编程中的数据的虚拟或真实地址。这是由编译器,操作系统和一些库控制的。所以简单地忽略它!

答案 3 :(得分:0)

简短回答:在x86-64机器上运行的用户模式程序:不,你不应该因为任何原因而认为


答案很长:可能会发生地址相同但绝对无法保证(至少在x86_64操作系统和机器上运行的程序中)。

我读到了一些关于虚拟/物理内存的混淆,以及地址是如何“随机”的,所以让我在高级视图中解释一下:

针对x86_64架构和操作系统(比如说Windows),您甚至不能假设操作系统本身会将所有组件加载到相同物理位置的内存中({{3}处的旧引导加载程序约定的一些例外情况) },我不知道它在UEFI环境中是如何工作的。)

分段后(使用与否取决于操作系统,通常Windows只为用户模式和内核模式设置一些普通段)就位,一旦切换到保护模式(或长)你再也无法控制操作系统管理隐藏复杂层和MMU相关操作的虚拟内存机制,为您的进程提供自己的地址空间。

此外还有安全措施:链接器可能会为您的可执行文件决定0000:7C00H,但在其他情况下,当base address被激活时,操作系统可以随意移动其模块和可执行文件安全目的。

结论:除非您处理非常低级的内容(例如物理地址或直接在外部设备上写入内存区域),否则您绝对不应该依赖于不同运行中变量的地址相同。对此有无保证