Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/303.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++_Random - Fatal编程技术网

C++ 初始化后的内存地址相同

C++ 初始化后的内存地址相同,c++,random,C++,Random,我在尝试创建没有rand()的随机数(只是因为我喜欢尝试一些东西)。使用在线编译器,这非常有效: #include <iostream> int randNum() { unsigned int x; size_t y = reinterpret_cast<size_t>(&x); return ((y >> 16) & 0x0000FFFF); } int main() { unsigned int x =

我在尝试创建没有rand()的随机数(只是因为我喜欢尝试一些东西)。使用在线编译器,这非常有效:

#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;
}
#包括
int randNum()
{
无符号整数x;
尺寸y=重新解释铸件(&x);
返回((y>>16)和0x0000FFFF);
}
int main()
{
无符号整数x=randNum();
标准::cout
我能理解为什么在线编译器每次都会给我一个新的内存地址,但为什么不在我的本地机器上呢

简短回答:因为标准中没有任何东西可以保证每次内存地址都相同或不同。这取决于您运行程序的位置(平台、操作系统)、编译方式以及更多因素


不要在你的代码中依赖这样的东西。最重要的是,如果你需要为一个真实的项目生成随机数,请使用
或PCG。

首先你需要一点背景知识。每个程序都从操作系统获得假RAM地址。它被称为虚拟地址空间,它允许进程的行为就像它有一个虚拟地址空间一样将整个内存转换为自身。进程不必担心与其他正在运行的进程冲突。当它尝试访问内存位置时,操作系统会将虚拟地址转换为真实的“物理”地址。如果对此感兴趣,您应该查找页表

一个进程有3个主存区域。堆栈、堆和文本。堆栈保留函数堆栈以及这些函数中定义的局部变量,例如无符号int x

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

好的,那么您可能想知道为什么堆栈底部总是从同一个位置开始。虽然它有一个小的摆动空间,但堆栈始终位于地址空间的顶端(高位),例如0xBFFF0000,并且它向低位“向下”增长。当您进行右移时(y>>16)实际上,您看到的是地址中变化最小的部分,恰好是页面索引,该部分可以由生活在同一页面上的数百个变量共享

可能影响堆栈底部位置的因素:

  • 地址空间布局随机化(ASLR),一种黑客对策。不一定在每次启动进程时都重新随机化
  • 环境变量,可以来自进程外部。不一定经常更改,并且取决于机器
  • CPU,操作系统,编译器
  • 更多
我敢打赌,在线编译器的情况就是每次在不同的机器上编译。每次运行时,它都在不同的机器上运行。由于许多人同时访问服务器,可能会对环境变量产生影响?而当您在本地机上运行时这里相对安静


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

这远远不是随机数生成算法。类型
size\t
不能保证与指针大小相同。请改用
intptr\t
。请定义“random”。例如,
44
是一个100%随机序列。它取决于程序基址和堆栈所在的平台。每次都是相同的是完全合理的。你从哪里知道这在任何有用的意义上都是随机的?我使用std::mt19937,就像我说的-我只是在胡闹,因为我注意到了在线编译器的内存地址是随机的。这让我想到了有关编译时和运行时内存分配的问题。虽然这个答案有很多不好的地方,但我否决它的最大原因是你自相矛盾。你注意到这一点是正确的“虚拟地址空间允许进程的行为就像它拥有整个内存一样”,但随后推测可能有“许多人访问服务器”。没错,但他们用自己的虚拟地址空间获得自己的进程。