初始化后相同的内存地址 [英] Same Memory Address After Initialization

查看:97
本文介绍了初始化后相同的内存地址的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在尝试创建不带rand()的随机数(只是因为我喜欢尝试东西)而感到困惑.使用在线编译器,效果很好:

I was messing around trying to create random numbers without rand() (just cuz I like to try stuff). Using an online compiler, this works great:

#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分配给相同的内存地址.

Compiling it locally on my computer, though...not so much. Every time I compile and run this, it assigns x to the same memory address.

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

I can understand why the online compiler would give me a new memory address every time, but why not on my local machine?

推荐答案

首先,您需要一些背景知识.每个程序都会从​​操作系统中获取伪造的RAM地址.这称为虚拟地址空间,它使进程的行为就好像它拥有整个内存一样.该过程不必担心与其他正在运行的过程发生冲突.操作系统尝试访问内存位置时,会将虚拟地址转换为实际的物理"地址.如果对此感兴趣,则应该查找页表.

First you need a little background. Each program gets fake RAM addresses from the OS. It's called the virtual address space, and it allows the process to behave as if it has the entire memory to itself. The process doesn't have to worry about conflicting with other running processes. When it tries to access a memory location, the OS translates the virtual address to the real "physical" address. If you're interested in this, you should look up page tables.

一个进程有3个主存储区.堆栈,堆和文本.堆栈保留您的函数堆栈以及在这些函数中定义的局部变量,例如您的unsigned int x.

A process has 3 main memory areas. The stack, the heap, and the text. The stack keeps your function stack as well as local variables defined in those functions, such as your unsigned int x.

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

Your randNum is simply returning the current location of the bottom of the stack. (btw, that is a security risk). With your simple test, randNum will always return the same result, because the address of x is based on the stack.

好吧,所以您可能想知道为什么堆栈基始终在同一位置开始.尽管它有一些摆动空间,但是堆栈始终位于地址空间的顶端(高数字),​​例如0xBFFF0000,并且它朝着低数字向下"增长.当您进行右移(y >> 16)时,您实际上正在查看的是地址中变化最小的部分,该部分恰好是页面索引,该部分可以由存在于页面上的数百个变量共享.同一页.

Ok so you might be wondering why the stack base always starts in the same place. Although it has a little wiggle room, the stack is always at the top (high numbers) end of your address space, for example, 0xBFFF0000, and it grows "downward", towards low numbers. When you do the right-shift (y >> 16) you're actually looking at the least varying part of the address, which just so happens to be the page index, the part that can be shared by hundreds of variables living on the same page.

可能会影响堆栈库位置的事物:

Things that can affect the location of the stack base:

  • 地址空间布局随机化(ASLR),一种黑客对策.不一定每次启动流程都重新随机化.
  • 环境变量,可以来自过程外部.不一定会经常更改,而取决于机器.
  • CPU,操作系统,编译器...
  • 更多???

我敢打赌,在线编译器所发生的就是每次您在不同的机器上进行编译时.每次您运行时,它都在另一台计算机上运行.随着许多人同时访问服务器,这可能会对环境变量产生影响吗?而当您在本地计算机上运行时,情况相对安静.

I would bet that's what happening with the online compiler is that each time you're compiling on a different machine. And each time you run, it's running on a different machine. With many people accessing the server at the same time, perhaps it's having an effect on environment variables? Whereas when you're running on your local machine, things are relatively quiet.

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

So I want to say that it was a great idea, and even though it doesn't work, I hope you learned something interesting.

这篇关于初始化后相同的内存地址的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆