c - 为什么 C 变量的内存地址不固定?

标签 c linux unix operating-system

我是一名刚刚了解虚拟内存的本科 CS 学生。我用以下程序做了一个实验。

#include<stdio.h>
int ready0; 
int main(void) {
  int ready;
  printf("ready0 at %p, ready at %p. \n", (void*)&ready0, (void*)&ready); 
} 

我觉得既然程序只和虚拟内存打交道,那么在程序看来应该是机器上运行的唯一进程。我也看了反汇编代码,看起来很有确定性。因此,如果我多次运行该程序,结果应该是相同的。然而,实验表明情况并非如此。为什么实验与我的预期不同?是什么导致我每次运行程序的结果都不一样?

如果您有兴趣,这里有几个在 Mac OS X Yosemite 上的实验结果。

$ ./sp
ready0 at 0x102b18018, ready at 0x7fff5d0e876c. 
$ ./sp
ready0 at 0x107c09018, ready at 0x7fff57ff776c. 
$ ./sp
ready0 at 0x10aa9c018, ready at 0x7fff5516476c. 
$ ./sp
ready0 at 0x10d56d018, ready at 0x7fff5269376c. 
$ ./sp
ready0 at 0x10da1c018, ready at 0x7fff521e476c. 
$ ./sp
ready0 at 0x109aff018, ready at 0x7fff5610176c. 
$ ./sp
ready0 at 0x107c31018, ready at 0x7fff57fcf76c. 
$ ./sp
ready0 at 0x10fab1018, ready at 0x7fff5014f76c. 

最佳答案

在过去,你通常是对的; main 入口处的堆栈指针经常是相同的(但它也取决于您的环境,参见environ(7) ...)。在您的 ABI 中给出了详细信息(特别是针对 Linux)规范与 execve(2)系统调用。你(和我)的 ABI 通常是 AMD64 ABI .

出于安全目的,当前系统具有ASLR - 地址空间布局随机化 -(您可以使用 echo 0 >/proc/sys/kernel/randomize_va_space 在系统范围内禁用它以 root 身份运行;这会打开一个安全漏洞)。因此 main 入口处的堆栈指针有点随机。

提示:如果您使用 gdb 观察点,您可能想要禁用 ASLR。

关于c - 为什么 C 变量的内存地址不固定?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30190079/

相关文章:

c - 用 LD_PRELOAD 覆盖 execve() 有时只有效

linux - gitlab dosent 恢复备份

bash - for循环找出unix中目录是否存在

c++ - 当包含 SDL 时,简单的 tcp echo 程序不工作?

c - 什么是堆栈空间重用

CURL 在发出 http 请求时的奇怪行为(错误 400)

c - C 中 main 函数的返回类型作为字符返回类型

Linux I2C 文件句柄 - 缓存安全吗?

bash - unix命令从单词的第一次出现和最后一次出现之间获取行并写入文件

python - 在 Python 中使用 os.system 调用多个命令