2016-01-20 53 views
1

下面的代碼編譯,但給分段故障時沒有使用GCC優化:GCC段錯誤,沒有優化

#include <stdio.h> 

#define n 10000000 

int main() 
{ 
    fprintf(stderr, "Array with size %ld\n", n * sizeof(double)); 
    double a[n]; 
    return 0; 
} 

$ gcc -O0 a.c && ./a.out 
Segmentation fault (core dumped) 
$ gcc -O1 a.c && ./a.out 
Array with size 80000000 

我-O1,-O2,-O3甚至與-oG它的工作原理進行測試。但用-O0它段錯誤。我正在使用GCC 5.3.0。

如果我刪除fprintf,或者如果我將數組更改爲靜態double [N],則沒有分段錯誤。

爲什麼?發生什麼事?

+0

不相關,但常量的常用命名約定全是大寫,並且比單個字母更具描述性,例如:'ARRAY_SIZE'。 – szczurcio

回答

5

您剛剛用盡堆棧空間。

double a[n];被分配到棧上,它的大小約爲40(80?)兆字節。

使之成爲static意味着它不再在堆棧上 - 並且打開優化將意味着編譯器從不實際分配它。

+0

你是什麼意思,「打開優化將意味着編譯器從來沒有實際分配它。」 ? – Heitor

+1

@Heitor - 編譯器可以告訴'a'沒有被使用,這是一個簡單的優化。 – Roddy

7

默認堆棧大小通常很小(如8MB)。您的數組大小可能太大並且會溢出堆棧。 你可以嘗試改變在* nix系統默認的堆棧大小:

ulimit -s unlimited 

在一般情況下,有沒有便攜式解決方案,以確定一個給定的數組分配與自動存儲時間(又名「堆棧」)是否將成功。因此,當您分配相當大的對象時,最好使用malloc()