溢出堆栈与巨大的局部变量?

sou*_*yar 5 c linux

据说每个过程都有8 mb的堆栈.该堆栈将用于存储局部变量.所以如果我的数组大小超过堆栈,它必须溢出?

 int main()
{
int arr[88388608];
int arr1[88388608];
int arr2[88388608];
while(1);
return 0;
}
Run Code Online (Sandbox Code Playgroud)

但我无法得到结果!

Ser*_*sta 5

欢迎来到优化编译器的世界!

由于as-if规则,编译器只需要构建与原始代码具有相同可观察结果的东西.所以编译器可以自由地:

  • 删除未使用的数组
  • 删除空循环
  • 存储来自堆栈外部的动态数组 - 因为main是一个特殊的函数,只能被环境调用一次

如果你想观察堆栈溢出(坏的,不是我们不错的网站:-)),你应该:

  • 使用一些代码来填充数组
  • 编译时删除所有优化并优先在调试模式下编译,告诉编译器尽可能准确地完成我写的内容

编译为时,以下代码将SIGSEGV与CLang 3.4.1配合使用 cc -g foo.c -o foo

#include <stdio.h>

#define SIZE 88388608

void fill(int *arr, size_t size, int val) {
    for (size_t i=0; i<size; i++) {
        arr[i] = val;
    }
}    
int main() {
    int arr[SIZE];
    int arr1[SIZE];
    int arr2[SIZE];

    fill(arr, SIZE, 0);
    fill(arr1, SIZE, 0);
    fill(arr2, SIZE, 0);
    printf("%d %d %d\n", arr[12], arr1[15], arr2[18]);

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

甚至这个代码在编译为-O2优化级别时工作正常...编译器现在对我来说太聪明了,我不够勇敢地彻底查看汇编代码,这将是了解实际执行内容的唯一真正方法!