2010-07-15 64 views
5

可能重複:
C programming, why does this large array declaration produce a segmentation fault?C(最大值)的大小在主

這是我第一次來這裏很抱歉,如果我打破一些規則,或者如果這已經回答過了。 我最近做了一個C程序中,我有

char buff[NR][1024*1024]; 

矩陣我需要NR = 128。因此,該程序將alocate 128MB。這是在main()中。我在有足夠內存的幾個系統上嘗試過,沒有編譯錯誤。在運行時,我收到所有系統上的分段錯誤。它適用於NR = 7,但不是8. 我將該代碼移到了主外部,使其成爲全局代碼。它甚至沒有崩潰128. 有誰知道爲什麼會發生這種情況? 編譯器是GCC

+0

[C編程,爲什麼這個大數組聲明會產生分段錯誤?](http://stackoverflow.com/questions/3049934/c-programming-why-does-this-large-array-declaration -produce-a-segmentation-fault) – 2010-07-15 13:32:33

回答

16

問題是你溢出的堆棧通常只有幾MB的大小(確切的大小取決於系統和編譯器選項)。您可以使用malloc來分配堆上的內存。

+0

如果他使用C,他應該使用malloc。 – 2010-07-15 13:01:05

+0

OP可以告訴編譯器使用更大的堆棧(http://stackoverflow.com/questions/156510/increase-stack-size-on-windows-gcc)..但基本上你是對的:) – akira 2010-07-15 13:01:30

+1

@SB :對,對不起!現在修復。 @akira:我不建議將堆棧大小增加到128MB。 – 2010-07-15 13:01:49

-4

分段錯誤可能還有另一個原因。使用諸如gdb之類的調試器來確定發生段錯誤的位置。

+1

-1:不,該程序幾乎肯定會因爲該行而崩潰。該代碼幾乎總是會導致崩潰,通常會因堆棧溢出錯誤或分段錯誤而異,具體取決於編譯器。 – Brian 2010-07-15 13:10:55

+0

這只是因爲這條線。當我評論它時,它會正常運行。 – Iustin 2010-07-15 13:19:09

+0

如果你評論它並且它正常運行,那麼這有什麼確切的影響? – Puppy 2010-07-15 13:37:35

5

當你把它放在main()中時,它會在堆棧上分配128MB,並且堆棧通常是有限的,其限制因系統而異。有些人可能只允許8MB,其他人可以使用 - 你的限制似乎是8MB,這是大多數Linux平臺的標準。如果這是類似POSIX的環境,則可以嘗試使用ulimit -s控制限制。

當您從main()中取出聲明並將其設置爲靜態時,它將以BSS段結束(除非您初始化它),並且僅受大多數系統上的堆空間限制(通常非常大和/或無限)。見http://en.wikipedia.org/wiki/Data_segment

但是,如果你想在本地和臨時性的,考慮分配NR兆字節自己:

#define MB (1024*1024) 
char *bufp = malloc(NR*MB) 
char *buf[NR]; 
int i; 

for (i = 0; i < NR; i++) 
    buf[i] = bufp + i*MB; 

你也可以分別分配每個MB塊,但我確實是這樣的情況下,你想記憶中的整個區域都是連續的。如果你正在編寫一個庫,如果你的程序將繼續做其他事情,請記住free(bufp)

+0

+1用於限定關於'free()'的評論,「如果你正在編寫一個庫,那麼你的程序會繼續做其他事情。」 – 2010-07-15 13:20:58

+0

@R ..:容易取悅。 :-) – integer 2010-07-15 13:34:28

0

或者您可以增加程序的堆棧分配大小。例如在VS 2008中,轉到項目屬性 - >鏈接器 - >並設置堆棧提交大小。

+0

我不同意這個想法(但我不會倒下你)。該堆棧不適合大量數據。 – tomlogic 2010-07-15 17:22:42

1

您的數組分配在堆棧上。堆棧的大小有限(取決於操作系統和鏈接器設置)。我認爲默認的堆棧大小對於win32(msvc編譯器)大約爲1兆字節,對於linux(gcc)大小爲8兆字節。任何比這更大的值將導致堆棧溢出,這將導致即時段錯誤。

可能的解決方案:在鏈接器設置

  1. 增加堆棧大小。
  2. 動態分配內存(使用malloc)。
  3. 使數組全局。
  4. 使數組靜態。

使變量全局/靜態將導致(至少在我看到的編譯器上)將它分配到堆棧之外 - 數據或代碼段中,這不會影響堆棧大小。

0

你可以使用malloc,你也可以經常在主要使用文件範圍之外聲明它。如果你需要在另一個c文件中使用extern。不建議使用這種方法,除非你有一個很好的理由有一個文件作用域變量(注意c沒有真正的「全局」變量,只是文件作用域可以用extern訪問)。 Google也是你在這些技巧上的朋友:)。您通常也可以找到與您的編譯器/操作系統一起使用的最大堆棧大小的設置。尋找「設置堆棧大小」。再次不推薦,學會使用malloc :)。