简体   繁体   中英

Difference between variables' addresses

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!

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.

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?

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 (eg, 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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM