一个程序编译改名字复制一份,为何两个在gdb中输出一样实际运行结果不一样?输出一个变量的地址

一个程序编译改名字复制一份,为什么两个在gdb中输出一样实际运行结果不一样?输出一个变量的地址
#include<stdio.h>
int main()
{
a =3;
printf("a's address is  %d\n",&a);
}
编译后复制后改名字比如原来叫test,另外一个叫test01.运行输出不一样。
然后 -g编译后,用gdb运行,test和test01输出一样。这是为什么了?请各位帮看看,谢谢!
------解决方案--------------------
研究Linux加载可执行文件相关源代码。
------解决方案--------------------
就像在饭店,你点两份相同的菜,并不能保证在后厨是同一个厨师在同一个煤具上做的一样。
你的程序运行在存储器的哪个区域、数组具体分配的地址,是由操作系统+编译系统等动态完成的,输出的地址相同也好、不同也好你没有必要去深究----有限的精力用在真正有用的地方吧
------解决方案--------------------
这不一样很正常啊,打印的是变量在栈上的地址,不同的进程栈是不一样的啊。
------解决方案--------------------
linux从2.6.12开始支持Address space layout randomization ,ASLR
进程用户空间的栈起始于STACK_TOP, 每个体系结构都必须定义STACK_TOP, 大多数都设置为TASK_SIZE, 即用户地址空间中最高的可用地址,在x86_32上该值为0XC0000000。如果内核设置了PF_RANDOMIZE,则起始点会减少一个小的随机量,使得栈的起始地址成为一个随机值,这样的话使用缓冲区溢出进行攻击就更加困难。

所以在内核开启了ALSR的情况下,你的程序别说换个名字,就是同一个程序连续运行两遍,其结果也不一样。

而gdb在运行时,fork之后,exec之前,会使用personality(orig_personality
------解决方案--------------------
ADDR_NO_RANDOMIZE)系统调用来关闭进程的ASLR,所以在gdb里运行输出值是一样的。