Same Memory Address After Initialization

3

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;
}

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?

c++
random
asked on Stack Overflow Dec 17, 2017 by Ethan Hannen

2 Answers

4

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

Short answer: because there's nothing in the Standard that guarantees that the memory address will be either the same or different every time. It depends on where (platform, OS) you're running the program, how you compiled it, and a thousand more factors.

Do not rely on things like this in your code. Most importantly, if you need random number generation for a real project, use <random> or PCG.

answered on Stack Overflow Dec 17, 2017 by Vittorio Romeo
0

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.

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.

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.

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:

  • Address Space Layout Randomization (ASLR), a hacking countermeasure. Doesn't necessarily re-randomize every time you start a process.
  • environment variables, which can come from outside the process. Won't necessarily change very often and depend on the machine.
  • CPU, OS, compiler...
  • more???

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.

answered on Stack Overflow Dec 17, 2017 by Humphrey Winnebago • edited Dec 17, 2017 by Humphrey Winnebago

User contributions licensed under CC BY-SA 3.0