c变量分配在内存,指针上

时间:2014-02-25 23:19:18

标签: c pointers memory-management

变量如何位于内存中?我有这个代码

int w=1;
int x=1;
int y=1;
int z=1;

int main(int argc, char** argv) {
    printf("\n  w %d",&w);
    printf("\n  x %d",&x);
    printf("\n  y %d",&y);
    printf("\n  z %d",&z);
    return (EXIT_SUCCESS);
}

并打印此

w 134520852
x 134520856
y 134520860
z 134520864

我们可以看到,当声明并分配了其他整数时,地址被移动了四个位置(我想是字节,看起来很逻辑)。但是如果我们不分配变量,就像在下一个代码中那样:

int w;
int x;
int y;
int z;

int main(int argc, char** argv) {
    printf("\n  w %d",&w);
    printf("\n  x %d",&x);
    printf("\n  y %d",&y);
    printf("\n  z %d",&z);
    return (EXIT_SUCCESS);
}

打印此

w 134520868
x 134520864
y 134520872
z 134520860

我们可以看到地址之间有四个位置,但它们不是有序的。为什么是这样?在这种情况下编译器如何工作?

如果你想知道我为什么这么问,那是因为我开始学习一些安全性而我正试图理解一些攻击,例如,整数溢出攻击是如何工作的,我是一直在玩C中的指针,通过添加比变量大小更多的位置来修改其他变量。

2 个答案:

答案 0 :(得分:2)

您的第一个示例初始化变量,生成不同的分配代码。通过查看gcc(gas)生成的汇编文件,我得到:

    .globl  _w
    .data
    .align 4
_w:
    .long   1
    .globl  _x
    .align 4
_x:
    .long   1
    .globl  _y
    .align 4
 _y:
    .long   1
    .globl  _z
    .align 4
 _z:
    .long   1

这基本上决定了内存地址。

你的第二个例子创建了未初始化的变量,正如Jonathan所说,这些变量进入BSS。汇编代码是:

.comm  _w, 4, 2
.comm  _x, 4, 2
.comm  _y, 4, 2
.comm  _z, 4, 2

这意味着你不能保证这些变量在内存中的顺序。

答案 1 :(得分:1)

第二组数字也是连续的,只是没有与源中的相同。我认为这样做的原因很简单,当你初始化变量时,编译器将它们按顺序排列,因为它维护了初始化的顺序,在第二种情况下,你只是得到一个随机顺序。

在任何情况下,这都取决于编译器;在这两种情况下,我得到相同的模式(有序,相隔4个字节)。