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

时间:2016-02-19 07:03:28

标签: c linux

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

 int main()
{
int arr[88388608];
int arr1[88388608];
int arr2[88388608];
while(1);
return 0;
}

但我无法得到结果!

1 个答案:

答案 0 :(得分:5)

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

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

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

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

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

以下代码在编译为cc -g foo.c -o foo

时将SIGSEGV与CLang 3.4.1进行对比
#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;
}

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