2016-02-19 28 views
5

據說每個進程都有8MB的堆棧。 該堆棧將用於存儲局部變量。 所以,如果我把最大的數組大小的堆棧,它必須溢出?溢出與巨大的本地變量的堆棧?

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

但是我無法得到結果!

+2

當你溢出堆棧時,你會得到*未定義的行爲*,它有時可能像預期的那樣工作。另外,這些日子的編譯器非常聰明。由於這些數組未被使用,編譯器爲什麼應該爲它們創建空間? –

+0

將arr的類型從「int」更改爲「volatile int」時會發生什麼? –

+2

另外,AFAIK,堆棧的大小可以在不同的系統上有所不同。 –

回答

5

歡迎來到優化編譯器的世界!

由於as-if規則,編譯器只需要構建與您的原始代碼具有相同可觀察結果的東西。 因此,編譯器,如果自由:

  • 刪除未使用的陣列
  • 移除空循環
  • 店從堆棧主外的動態數組 - 因爲主要是隻應稱爲特殊功能一旦受到環境

如果你想觀察堆棧溢出(壞的,而不是我們的漂亮的網站:-)), 你應該:

  • 使用一些代碼來填充陣列
  • 編譯刪除了所有優化和preferently在調試模式來告訴編譯器做什麼,我儘可能準確,你可以寫

下面的代碼確實SIGSEGV與鐺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; 
} 

當作爲-O2優化級別編譯連這個代碼工作正常...編譯器現在是對我來說很聰明,而且我沒有足夠的勇氣徹底地看待彙編代碼,這將是理解實際執行的唯一真正方法!

+0

@靈溪:你的回答幾乎是正確的。如果你把它翻譯成C並且取消刪除它(並且在評論中對我進行ping),我會加倍努力,因爲我只是圍繞你的解釋 –