c变量分配内存,指针

标签 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 中的指针来修改其他变量,方法是添加比变量大小更多的位置等等。

最佳答案

您的第一个示例初始化变量,这会生成不同的分配代码。通过查看 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

这意味着您无法保证这些变量在内存中的顺序。

关于c变量分配内存,指针,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22028370/

相关文章:

java - 使用 JNI 将数据类型从 Java 传递到 C(反之亦然)

c - 指针比较与字符串比较 strcmp 的性能

c++ - 使用 `std::shared_ptr` 时有效地节省内存/编程

c# - 字符串生成器的内存分配。内存中发生了什么? StringBuilder 与字符串

c++ - HoughLinesP 和 opencv 内存管理

c - 循环中的malloc,所有分配的 block 都是连续的吗?

c - memcpy 部分复制到自身

c - Sys V ABI 规范(i386 和 AMD64)中描述的标准 "Function Calling Sequence"是否适用于静态 C 函数?

c++ - 为什么我的程序停止工作?我的指针错了吗?

c - 为什么即使设置了处理程序也没有在函数中捕获 float "division-by-zero"异常?