Why do variable addresses differ by a specific amount each time I run a program (as in "printf("%d %d\n", &a, &b);". It will print "1000 988" in one run, "924 912" in another, "1288 1276", and so on and so forth)? Does the compiler occupy a set amount of memory after each variable declaration where nothing can be written? If yes, what does it depend on? Using some variables in a program of mine, the smallest difference between them was 12 bytes, and it reached up to 212. This was the only case where the difference was not a multiple of twelve (in other cases it was 24, 36 or 48 bytes). Is there any reason behind that? Since my variables were of type int (occupying 4 bytes in my system), could the difference between my variable addresses be less than 12 (for example 4)? Do those address differences depend on the variable types? If yes, in what way? Thank you in advance!
-
Your OS provides *Virtual Memory Address Space* within which all applications run. When your code executes, the memory manager for your OS fills the applications request for memory and the memory is released (for reuse wherever you OS needs it) when your code completes. Sometimes you can get the exacts same address for each variable on successive runs, sometimes not, it's up to what your OS provides to the app when it is started. (from you app's standpoint -- "It's like a box of chocolates...") – David C. Rankin May 14 '17 at 09:59
-
Are you aware that printing a pointer with `%d` is UB? Your compiler probably warns you. Anyway, the proper format is `%p`. – Deduplicator May 14 '17 at 10:40
-
@Deduplicator I am aware of that. I only used it because it it easier to do arithmetic between decimals, rather than hexadecimals. In this case, the results printed should be correct. – Leet May 14 '17 at 10:47
-
@DavidC.Rankin: Thank you for the clarification! – Leet May 14 '17 at 10:53
3 Answers
Most OSes today use address-space layout randomization in order to make it harder to write certain kinds of malware. (The kind that writes code to memory and then tries to get the program to hand over control to it; now has to guess what address to get the program to jump to.) As a result, variables won’t be at the same addresses every time you run a program.
Depending on the type of the variable, how it’s allocated and which OS and architecture you’re running on, the size and alignment of variables will vary. The compiler and runtime might or might not always put them on a four-, eight- or sixteen-byte boundary. For example, the x86_64 function-call ABI always starts a function’s stack frame on a sixteen-byte boundary, and some implementations of malloc()
always return an address divisible by sixteen because that’s required to store vectors on some CPUs.
If you want to know what the compiler is doing, you can try compiling to assembly. On gcc or clang, you can do this with the -S
flag.

- 14,674
- 2
- 34
- 49
If you're asking why the memory address for a variable differs in between different executable runs the answer is ASLR, which exists to make it harder to exploit security issues in code (see https://en.wikipedia.org/wiki/Address_space_layout_randomization).
If you disable ASLR you will get the same address for a given variable each time you run your executable.
See also Difference between gdb addresses and "real" addresses?
-
I am asking why, if I declare 2 variables like this "int a, b;" and proceed to print their addresses, as in "printf("%d %d\n", &a, &b);", their addresses always differ by the same amount. For example, in one run, printf would print (500 488) and in another (612 600) and so on and so forth. Taking a second look in my question above, I did not make myself clear indeed. Still, thank you for your answer. I am interested in knowing that as well. – Leet May 14 '17 at 10:33
-
If you declare "int a,b" they are both on the stack and the offset between them should always be sizeof(int). – diciu May 14 '17 at 10:53
-
printf("%d\n", sizeof(int)); prints 4. However, the offset is not 4. It is 12 or more. Every case I run the code. – Leet May 14 '17 at 11:04
-
I get 4 on both OS X and Linux using llvm and gcc respectively. The code is `int a,b; printf("%p %p\n", &a, &b);` – diciu May 14 '17 at 11:22
-
Using EXACTLY the same code as you, I am getting: 006FFDD4 006FFDC8, so the differences in hexadecimal are the same as well. That's the reason I was curious. Why would be greater a space than the variable's size be occupied? As Davislor above said, in some cases that may happen. – Leet May 14 '17 at 11:26
-
The only explanation I can think of is alignment but I don't know of any compiler that using "standard" options would align integers in the way you're describing. What compiler are you using and what compiler options are being used? – diciu May 14 '17 at 11:34
-
I have no idea how to check that. I am a noob as of yet. I am using visual studio 2k17, if this gives you any useful info. Also, the output I am getting from building the program is this: 1>------ Build started: Project: ConsoleApplication1, Configuration: Debug Win32 ------ The rest is just directory paths. – Leet May 14 '17 at 11:52
-
-
No worries mate! Thank you for your help thus far! You've given me food for thought. – Leet May 14 '17 at 13:18
Your linker (and to some degree, your compiler) lays out the address space of your application. The linker typically builds a relocatable image based at some address (e.g., zero). Apparently, your loader is placing the relocatable image at different locations when it is run.
Does the compiler occupy a set amount of memory after each variable declaration where nothing can be written?
Typically no UNLESS, the next variable needs to be aligned. Variables are normally aligned to addresses that are multiples of the variable's size.
It sounds like your compiler is allocating memory for something that you simply are not accounting for.

- 20,574
- 3
- 26
- 62