简体   繁体   English

变量地址之间的差异

[英]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)? 为什么每次运行程序时变量地址都会有不同的特定数量(如“printf(”%d%d \\ n“,&a,&b);”。它将在一次运行中打印“1000 988”,“924 912“在另一个,”1288 1276“,依此类推)? 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). 在我的程序中使用一些变量,它们之间的最小差异是12个字节,它达到212.这是唯一一个差异不是十二的倍数的情况(在其他情况下它是24,36或48)字节)。 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)? 由于我的变量是int类型(在我的系统中占用4个字节),我的变量地址之间的差异是否可以小于12(例如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. 例如,x86_64函数调用ABI总是在16字节边界上启动函数的堆栈帧,而malloc()某些实现总是返回可被16整除的地址,因为这需要在某些CPU上存储向量。

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. 在gcc或clang上,您可以使用-S标志执行此操作。

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 ). 如果你问为什么变量的内存地址在不同的可执行运行之间有所不同,那么答案就是ASLR,这是为了更难以利用代码中的安全问题(参见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. 如果禁用ASLR,每次运行可执行文件时,您将获得给定变量的相同地址。

See also Difference between gdb addresses and "real" addresses? 另请参阅gdb地址和“真实”地址之间的区别?

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. 通常没有UNLESS,下一个变量需要对齐。 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. 听起来你的编译器正在为你根本不考虑的东西分配内存。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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