Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 对于程序的不同运行,全局变量的地址是否相同?_C++_Virtual Memory - Fatal编程技术网

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

C++ 对于程序的不同运行,全局变量的地址是否相同?,c++,virtual-memory,C++,Virtual Memory,考虑下面的代码片段 int i=10; int main() { cout<<&i; } inti=10; int main() { 答案很简单:视情况而定:-) 如果您的操作系统启动的程序总是在相同的环境中,并且虚拟内存范围看起来总是相同的,那么输出应该总是相同的 但是,如果在不同的硬件上运行相同的操作系统(可能有不同数量的可用ram),可能会在不同的地址中运行,但通常地址也是相同的,与硬件无关 但是你永远不要期望结果是一样的!简而言之:不要考虑你的程序中数据的虚

考虑下面的代码片段

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

答案很简单:视情况而定:-)

如果您的操作系统启动的程序总是在相同的环境中,并且虚拟内存范围看起来总是相同的,那么输出应该总是相同的

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


但是你永远不要期望结果是一样的!简而言之:不要考虑你的程序中数据的虚拟地址或真实地址。这是由编译器、操作系统以及可能的一些库控制的。所以干脆忽略它吧!

虚拟地址将由链接器决定。物理地址将随每个lo而变化广告。

简短回答:在x86-64机器上运行的用户模式程序上:不,您不应该出于任何原因假定它曾经运行过


详细回答:地址可能是相同的,但这绝对不能保证(至少在x86_64操作系统和机器上运行的程序上是如此)

我读到了一些关于虚拟/物理内存的混淆,以及为什么地址是“随机”的,所以让我从高层角度解释一下:

以x86_64体系结构和操作系统(比如Windows)为目标,您甚至不能假设操作系统本身会将其所有组件加载到相同物理位置的内存中(对于旧引导加载程序约定的一些例外,我不知道在UEFI环境中如何工作)

分段后(使用与否取决于操作系统,通常Windows只为usermode和kernelmode设置一些普通分段),一旦切换到保护模式(或长模式)您同样无法控制操作系统如何管理虚拟内存机制,该机制隐藏了复杂的层次和与MMU相关的操作,从而为您的进程提供了自己的地址空间

此外,还有一些安全措施:链接器可能会决定可执行文件的位置,但在其他情况下,当被激活时,操作系统可以出于安全目的随意移动其模块和可执行文件


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

如果被禁用,你总是会得到相同的地址。如果启用ASLR,你会得到不可预测的地址。

@AndreasBjørn在RAM中的“random”并不完全意味着这一点。&我想我会返回virt变量的虚拟地址,因此它不应该与物理内存的随机访问有关。为什么要依赖于此?这取决于您的操作系统和其他因素。没有单一的答案。@KeithThompson我这样做只是为了理解一些概念,而不是实际编码它。在Windows上,虚拟地址将是nker决定,只要模块可以在首选地址加载。在使用PIC代码的系统上,虚拟地址将由加载程序决定。