初始化后相同的内存地址

Same Memory Address After Initialization

本文关键字:内存 地址 初始化      更新时间:2023-10-16

我在尝试创建无rand()的随机数(Cuz我喜欢尝试一些东西)而乱七八糟。使用在线编译器,这很棒:

#include <iostream>
int randNum()
{
    unsigned int x;
    size_t y = reinterpret_cast<size_t>(&x);
    return ((y >> 16) & 0x0000FFFF);
}
int main()
{
    unsigned int x = randNum();
    std::cout << x;
    return 0;
}

不过,在我的计算机上本地编译它……不是很多。每次我编译并运行此操作时,都会将X分配给相同的内存地址。

我可以理解为什么在线编译器每次都会给我一个新的内存地址,但是为什么不在我的本地机器上?

我可以理解为什么在线编译器每次都会给我一个新的内存地址,但是为什么不在我的本地机器上?

简短的答案:因为标准中没有任何东西可以保证每次都相同或不同的内存地址。这取决于您正在运行该程序的(平台,操作系统)的位置,如何编译该程序以及一千个因素。

do 不是依靠代码中的类似内容。最重要的是,如果您需要一个真实项目的随机数,请使用<random>或PCG。

首先,您需要一些背景。每个程序都会从操作系统中获取虚假的RAM地址。它称为虚拟地址空间,它允许该过程的行为,好像它具有整个内存。该过程不必担心与其他运行过程发生冲突。当它试图访问内存位置时,OS将虚拟地址转换为真实的"物理"地址。如果您对此感兴趣,则应查找页面表。

一个过程有3个主要存储区域。堆栈,堆和文字。该堆栈可保留您的功能堆栈以及这些功能中定义的局部变量,例如您的无符号int x。

您的Randnum只是返回堆栈底部的当前位置。(顺便说一句,这是安全风险)。通过您的简单测试,Randnum将始终返回相同的结果,因为X的地址基于堆栈。

好吧,所以您可能想知道为什么堆栈基座总是在同一位置开始。尽管它有一个小的摆动室,但堆栈始终位于地址空间的顶部(高数字)端,例如0xbfff0000,并且它的"向下"增长到低数字。当您进行正确的换档(Y>> 16)时,您实际上是在寻找地址的最小部分,这恰好是页面索引,该部分可以由数百个居住在该地址的变量共享同一页。

可能影响堆栈基础位置的事物:

  • 地址空间布局随机化(ASLR),一种黑客对策。不一定每次启动过程时都会重新旋转。
  • 环境变量,可以来自该过程。不一定会经常更改并取决于机器。
  • CPU,OS,编译器...
  • 更多???

我敢打赌,在线编译器中发生的事情是,每次您在其他机器上编译时。每次您运行时,它都在另一台计算机上运行。随着许多人同时访问服务器,也许会对环境变量产生影响?而当您在本地机器上跑步时,情况相对安静。

所以我想说这是一个好主意,即使它不起作用,我希望您学到了一些有趣的东西。