TAG

首都機能移轉 (2) 歌詞 (2) 靠北文 (40) 戲言 (30) 糟糕 (7) ACG (23) Assembly (2) Boost (2) C (31) C++ (69) CMake (4) CSIE (67) Debian (34) Design_Pattern (2) Django (1) Eclipse (1) en_US (13) FFmpeg (3) FoolproofProject (26) FreeBSD (2) Git (4) GNU_Linux (65) IDE (5) Java (11) JavaScript (19) KDE (15) Khopper (16) KomiX (3) Kubuntu (18) Life (1) Lighttpd (2) Mac_OS_X (2) Opera (1) PHP (2) PicKing (2) Programing (21) Prolog (1) Python (7) QSnapshot (2) Qt (30) Qt_Jambi (1) Regular_Expression (1) Shell_Script (7) Talk (98) VirtualBox (7) Visual_Studio (13) Windows (18) zh_TW (36)

2007年6月11日 星期一

C++陣列過大造成stack overflow

如果你有機會在 local 宣告一個夠大的陣列的話,應該會發現雖然編譯無誤,但是在程式甫執行就立刻惡性停止。這是因為區域變數,記憶體會被分配在 stack 區段,而這塊區域一般來說並不夠大,大到可以放巨大陣列,因此只要陣列太大,就會立刻 stack overflow。
解決這個問題的方法有三種,其中一種是把變數設為 global variables。global variables 不會被配置到 stack 區。然而我們知道,不加 const 的全域變數是非常不被鼓勵的寫法,這會使得程式的維護性降低。
第二個方法是在編譯器的選項裡調整 stack 區的大小,這我個人也不推薦。
而第三種方案是,在宣告時不要預先宣告好陣列,而是用 dynamic array 的方式,先宣告好 pointer,再手動分配一段記憶體給它,C++ 用 new,C 就用 malloc。
bool prime[20000000]; //這個會爆
bool* prime = new bool[20000000]; //這個不會
這樣就算設為 local variable 也不會 stack overflow。因為手動配置的區段會被分配在 heap,此區沒有如 stack 區段的大小限制。
最後請記得,自己手動分配出來的記憶體,請自己回收;回收完之後請再養成習慣,把空懸的 pointer 指回 NULL,這就是所謂的小三元(?)[?]
BTW,要對陣列做初始化,不要用 for,這樣速度很慢,C++ 的 <algorithm> 裡有個比較乾脆的函式,就是 fillfill_n,可以直接設定一塊容器的值。C 可用 <string.h> 的 memset。用法請自己問男人或是 Google。
至於 stack 或 heap 是什麼....請去問你們的組合語言或計算機組織的老師吧= =

6 則留言:

  1. Windows 裡面沒有男人........

    回覆刪除
  2. 初次見面您好,請問此文連結可以貼至PhotoCap的論壇區去嗎?剛好有人問到此問題。

    回覆刪除
  3. 請便 :P
    能幫上您的忙我也很高興

    回覆刪除
  4. global varible 會被配置到 heap 區
    It that true?

    回覆刪除
  5. 剛剛去查了一下, 好像是 DATA segment
    沒有查證是我的疏忽 orz

    回覆刪除
  6. 剛剛在 Windows 上用 Visual Studio 測試 C 沒有這個問題耶。

    回覆刪除