Search code examples
cvariablesmemory-address

Why the address of variables is identical even across reboot?


I tried this program to know how variables are stored and have a doubt.

I compiled the above code and an executable file is created and I noted the output(address of a,b,c,d) then i deleted the executable file and restarted my pc and after that when I modify the value of variables and re-execute the code. I find the same address is being assigned to variables as previously.
This is what I am not understanding, since variables are stored in RAM and RAM is non-constant.

How is the address same even after restart?

#include <stdio.h>
int main(){
    int a=21, b=22, c=23, d=24;
    printf("%p, %p, %p, %p", &a, &b, &c, &d);
}

Output:

0xffffcbec, 0xffffcbe8, 0xffffcbe4, 0xffffcbe0

Solution

  • A bit of nitpicking, I only do so because I suspect that there are actual misunderstandings behind the imprecise phrasing which might cause your question.

    when i modify the value of variables and re-execute the code. I find the same address is being assigned to variables as previous.

    • Modifying the value of an existing variable does not change the address, it is like having a new family move into a building; that won't change the address.
    • Addresses are not assigned to variables, values are. (Though the values assigned to pointer variables are addresses, but that does not change the address of the pointer variable either, only its value; like a letter in the old house, which notes the new address of the family previously living there, see "linked list"; the address of the old house is however still the same).
    • Addresses of global variables (something different to what is in your code) are determined during loading (between whatever you do to have your program executed, e.g. double clicking or typing into a CLI, and its execution), possibly with intentional randomisation, but also possibly in a deterministic way.
    • Addresses of local variables (like in your code) are determined between calling them and executing them (the model for that time is the "stack frame setup"), also possibly with intentional randomisation, but also possibly in a deterministic way.

    Now to the core of what you wonder about, why you observe adresses of variables as the same in many many situations.

    That is not guaranteed (but it can happen and not only by two random 64 bit integers happening to be the same).
    Even if you reboot the computer in between.
    Eeven if you delete and rebuilt the executables in between.
    Even if two programs (or two copies of the same program) are running at the same time.
    Even if those variables have different values in each of the programs.
    Even if they have different types in each of the programs.
    Even if the two outputs come from two processes of the same program and with different values in the two variables of different types at the same address.

    Your observations are also misleading, because in modern PCs the fact that the address which you output is the same does not mean the variable is in the same place in physical memory.
    The memory management of modern software (hardware is also involved; lookup "PMMU") means that their view of their own memory (called their virtual address space) is different from what happens in physical memory/RAM.

    Actually there are (security-related) mechanisms which I would expect to explicitly attempt to change the location/address of variables from execution to execution of your program, i.e. the intentional randomisation mentioned above.
    This was already mentioned as "ASLR" in the comment by nanofarad and is described here: https://en.wikipedia.org/wiki/Address_space_layout_randomization
    I would expect that to be active in default setups in practially all environments nowadays. I suspect hence, that there is some unusual configuration at work during your observations. Or maybe you are experimenting with very old compiler versions.

    But the fact that the address IS the same really does not mean anything in many cases. If those mentioned mechanisms do not act, then the same local variable (in your case, but also global variables otherwise) can always end up on the same location, even if you would move your test code into a different function and call it from main(), even several times; as long as you always observe outputting directly from main() or always observe outputting from a called function (otherwise see below).

    If I may speculate, you could change your program for an experiment, by using a subfunction like your main, a wrapper subfunction which calls that main-like subfunction and then call the main-like subfunction and the wrapper function from main(). In that case your local variables should end up in two different locations (the concept of a "stack" is not actually used by the C standard, but that is the model I am referring to here).

    Pseudo code:

    • main()
      • calls main-like subfunction
        • outputs addresses of local variables, like your code
      • calls wrapper
        • calls main-like subfunction
          • outputs addresses of local variables, like your code

    You should see different addresses then, with different values or same values not mattering.