为什么在每次执行同一个二进制映像时,局部变量的地址会不断变化?

Dar*_*n L 3 c addressing memory-layout

我有如下的小代码片段:

char global=100;        

void main()
{
            char p = NULL;
            printf("%p\n", &p);
            printf("%p\n", &global);
}
Run Code Online (Sandbox Code Playgroud)

在编译并生成二进制可执行映像之后,在每次执行相同的二进制可执行文件时,我会看到本地变量的不同虚拟内存地址p.
但是,全局变量的虚拟内存地址global保持不变.我理解C内存布局; 并且我希望在每次执行时使用相同的二进制图像为给定变量提供相同的内存位置.

在运行时为本地变量分配的虚拟地址的原因是什么?
只有一个功能,没有机会改变功能的执行顺序,从而改变堆栈存储器布局.

运行此程序4次的结果:

0x7fff181b4b2f
0x601034

0x7ffe34abd62f
0x601034

0x7ffe2813b98f
0x601034

0x7fffcef6b52f
0x601034
Run Code Online (Sandbox Code Playgroud)

dbu*_*ush 5

这通常是由地址空间布局随机化引起的.它是一种安全技术,旨在防止某些类型的攻击,例如缓冲区溢出.

托管环境中的局部变量通常存储在堆栈中.在这种情况下,堆栈的虚拟内存地址会发生变化,以致有人试图超出缓冲区并运行任意代码,将无法预测恶意代码出现的位置.