变量如何位于内存中?我有这个代码
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中的指针,通过添加比变量大小更多的位置来修改其他变量。
答案 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个字节)。