c - x86-64 中的内存分配

标签 c gcc memory 64-bit

我只是想让自己清楚地了解 x64 架构上的 c 中的内存分配(如果我可以这样调用它的话)。

我有一个程序可以简单地输出变量在内存中的位置。我运行了几次,然后发现发生了一些奇怪的事情:

代码行:

printf("[*] test_val @ 0x%016llx = %d 0x%016llx\n", &test_val, test_val, test_val);

第一次:

[*] test_val @ 0x00005612f1edb050 = -72 0x00000000ffffffb8

第二次:

[*] test_val @ 0x000055ec3b64f050 = -72 0x00000000ffffffb8

第三次:

[*] test_val @ 0x00005577e99d4050 = -72 0x00000000ffffffb8

似乎变量test_int 的内存位置每次都不同,除了前 2.5 位(00005)和最后 1.5 位(050 部分不变)。

毫无疑问,但在我正在学习的书中,这个地址一直是不变的。主要区别在于本书是关于 32 位架构的。

我是否正确理解内存是在 x64 系统中动态分配的?考虑到我们知道最后 1.5 位(在本例中为 050)这一事实,是否有任何方法可以“预测”变量的位置?

最佳答案

There would've been no question, but in the book I'm learning by this address is constant all the time.

如果这本书实际上声称地址在同一程序的多次运行中保持不变,那是错误的。事实上,即使在一个程序的同一次运行期间,具有自动存储持续时间的局部变量也可能在同一个运行实例中的多个调用中获得不同的地址。考虑:

void foo()
{
    volatile int a = 12345;
    printf("%p\n", (void *)&a);
}
void bar()
{
    printf("In bar\n");
    foo();
}
int main()
{
    foo();
    bar();
    return 0;
}

我得到输出:

00B6FE58
In bar
00B6FE54

这是因为当输入 foo 时,对 bar 的调用会在堆栈上创建另一个帧,从而为 a 提供不同的地址。一般来说,我认为唯一可以安全推理的是,如果变量具有静态存储持续时间,则其地址应该单次运行程序。

为什么多次运行你的程序会观察到不同的地址,那是因为:

  1. C 标准与 ABI、可执行文件格式和加载程序无关。
  2. Advances in security通常意味着您不应期望在现代操作系统上多次运行用户模式程序时看到相同的地址。

关于c - x86-64 中的内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54874903/

相关文章:

编译 XFCE4 面板插件

c - 在C语言编程中制作连续的字符串

c++ - 小 N 的 std::map 与 unordered_map 内存占用

c - C : stack or global variable? 中的 RAM 优化

c - 如何编写段错误处理程序,以便不重新启动错误指令? (C 和 Linux)

c - 具有不同长度数组成员的结构数组 C

c++ - 如何从 g++ 生成的目标代码中剥离表示源头文件绝对路径的字符串

将 ascii 十六进制字符串转换为字节数组

memory - 内存中字节序 : Bits in a Byte vs. 字节

python - Sklearn.KMeans : how to avoid Memory or Value Error?