c - 关于C中栈分配的问题

标签 c memory-management stack

以下代码段有意访问 t[4] 之后的下一个 sizeof(int) 字节,因此我知道这里犯的错误。我这样做只是作为一个实验,看看编译器如何处理堆栈分配。

int t[5], i;

for (i = 0; i <= 5; i++) {
   t[i] = 0;
}

当在 Windows 上使用 GNU C 编译器的移植版本执行此代码时,程序总是陷入无限循环。我确信这只会发生,因为 ti 在堆栈上依次分配,并且 t[5] 指向到与 i 变量相同的地址。因此,当执行t[5] = 0时,程序实际上将i的值设置为零。

但是,当使用不同版本的 GNU C 编译器编译此文件时,我从未遇到无限循环。 t[5] 的地址与 i 的地址不同。

我的问题是,为什么会出现这种不同的行为?我知道您不应该对此结果做出任何假设,但是堆栈分配不应该以相同的方式发生吗?

我真正好奇的是编译器如何管理这些堆栈分配。有垫子吗?顺序是否始终与源代码中的顺序相同?显然这与 C 标准无关,并且实现之间存在差异,甚至同一编译器的不同版本也存在差异。我很好奇在这种特殊情况下可能的结果和考虑因素是什么。

最佳答案

您正在处理未定义的行为。编译器不需要按顺序布置自动变量(就像它们出现在源代码中一样)。其中一些可能位于寄存器中,或者它们可能以不同的方式排序,例如,较小的偏移量更便宜。

这样的要求仅适用于结构体的成员(成员之间具有任意填充)。

Is there any padding?

是的,编译器会遵守每种类型的对齐要求并相应地放置变量。

Is the order always the same as in the source code?

不,但这是许多漏洞利用所依赖的东西。缓冲区溢出可能会覆盖相邻的变量并危及整个程序的执行。

关于c - 关于C中栈分配的问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35622441/

相关文章:

mysql - 开发 C 和 MYSQL 应用程序时出现构建错误

ios - 请帮我找出这个 Objective-C 方法 (iOS) 中的内存泄漏

python - 使用 Tkinter 和 Python 提升图像

c++ - 比较队列和堆栈的内容

Linux AT&T 命令行参数

c - 使用 fgetc C 从文件读取字符串时出现问题(不使用 fscanf 等)

c - 访问越界内存后,段错误不会立即出现

c - 如何在arm-none-eabi-gcc中指定Cortex-A53?

ios - UIButton 从内存中释放?

c - 不同上下文中char数组的内存分配