【问题标题】:Difference between memory addresses of variables is constant变量的内存地址之间的差异是恒定的
【发布时间】:2015-06-07 03:43:40
【问题描述】:

我运行了以下代码,这是我得到的输出:

#include <stdio.h>

int main()
{
    int x = 3;
    int y = x;
    printf("%d\n", &x);
    printf("%d\n", &y);
    getchar();
    return 0;
}

Output:

3078020
3078008

现在,每次我运行程序时,输出都会发生变化,但是 x 的位置与 y 的位置之间的差异总是 12。我想知道为什么。

编辑:我明白为什么差异是恒定的。我不明白的是为什么差值具体是12,为什么后面定义的y的内存地址小于x的。

【问题讨论】:

    标签: c pointers memory int memory-address


    【解决方案1】:

    由于address space layout randomisation (ASLR) 等保护措施,地址本身很可能会发生变化。

    这样做是为了减少代码受到攻击向量的可能性。如果它总是在同一个地址加载,那么攻击成功的可能性就更大。

    通过在每次加载时移动地址,攻击在任何地方(或在任何地方,真的)都变得更加困难。

    然而,事实上这两个变量都将在一个堆栈帧中的堆栈上(假设实现甚至 使用一个绝对不能保证的堆栈),差异他们之间的 em> 不太可能改变。

    【讨论】:

    • 感谢(n+1)th 先生的好回答。 :-)
    • 为什么具体是12?
    【解决方案2】:

    在您的代码中,

    printf("%d\n", &x);
    

    不是打印指针值的正确方法。你需要的是

    printf("%p\n", (void *)&x);
    

    也就是说,地址之间的差异是恒定的,因为这两个变量通常放置在堆栈中的连续内存位置。但是,AFAIK 在c 标准中并不保证这一点。唯一可以保证的是sizeof(a) [数据类型的大小] 将针对特定平台进行修复。

    【讨论】:

    • @paxdiablo 先生,我说的对吗这在 c 标准中没有保证
    • 是的,我很确定这是对的。例如,指针值在结构或数组中受到一些限制,但不同的变量不需要按任何特定顺序排列。
    • @paxdiablo 感谢您的评论。 :-)
    • 从技术上讲,不同变量之间的指针运算是未定义的——但实际上通常是可以预测的。
    【解决方案3】:

    要打印变量的地址,您必须使用%p 而不是%d

    要打印整数值,您只需提供%d

    printf("%d\n",x);// It will print the value of x
    printf("%p\n",(void*)&x);// It will print the address of x.
    

    来自printf的手册页

    p      The void * pointer argument is printed in hexadecimal
    

    【讨论】:

      猜你喜欢
      • 2017-10-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-06-05
      相关资源
      最近更新 更多