初始化后相同的内存地址
Same Memory Address After Initialization
我在尝试创建无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,编译器...
- 更多???
我敢打赌,在线编译器中发生的事情是,每次您在其他机器上编译时。每次您运行时,它都在另一台计算机上运行。随着许多人同时访问服务器,也许会对环境变量产生影响?而当您在本地机器上跑步时,情况相对安静。
所以我想说这是一个好主意,即使它不起作用,我希望您学到了一些有趣的东西。
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 为什么 vector 的随机访问迭代器给出与指针不同的内存地址?
- 使用内存地址访问结构的属性值
- 为什么C++总是显示十六进制内存地址,而不仅仅是整数?
- 将布局映射到内存地址
- 为什么同一个变量的内存地址不同?
- 无法将内存地址转换为值
- 给定特定内存地址的数组的动态内存分配
- 在 Microsoft Access SQL 中调用自定义 DLL 函数时传递的内存地址无效
- 获取 R 数据帧的内存地址
- c++ 编译器是否保护常量内存地址免受任何更改?
- 如何防止矢量的内存地址更改
- cout 打印内存地址而不是值
- 如何运行外部程序,向其传递内存地址以读取/写入?
- 循环中的变量被设置为下一个数组的元素始终具有相同的内存地址?
- 重载 ostream << 运算符,指针作为参数,导致输出上的内存地址
- C++在变量的内存地址上做什么来"deallocate"它?
- 在指向现有内存地址的 hpp 文件中声明成员函数的最佳方法
- 为什么我无法获取 MSVS2019 / C++ 中字符或uint8_t变量的内存地址?