如果你有機會在 local 宣告一個夠大的陣列的話,應該會發現雖然編譯無誤,但是在程式甫執行就立刻惡性停止。這是因為區域變數,記憶體會被分配在 stack 區段,而這塊區域一般來說並不夠大,大到可以放巨大陣列,因此只要陣列太大,就會立刻 stack overflow。
解決這個問題的方法有三種,其中一種是把變數設為 global variables。global variables 不會被配置到 stack 區。然而我們知道,不加 const 的全域變數是非常不被鼓勵的寫法,這會使得程式的維護性降低。
第二個方法是在編譯器的選項裡調整 stack 區的大小,這我個人也不推薦。
而第三種方案是,在宣告時不要預先宣告好陣列,而是用 dynamic array 的方式,先宣告好 pointer,再手動分配一段記憶體給它,C++ 用 new,C 就用 malloc。
最後請記得,自己手動分配出來的記憶體,請自己回收;回收完之後請再養成習慣,把空懸的 pointer 指回 NULL,這就是所謂的小三元(?)[?]
第二個方法是在編譯器的選項裡調整 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> 裡有個比較乾脆的函式,就是 fill 或 fill_n,可以直接設定一塊容器的值。C 可用 <string.h> 的 memset。用法請自己問男人或是 Google。
至於 stack 或 heap 是什麼....請去問你們的組合語言或計算機組織的老師吧= =
Windows 裡面沒有男人........
回覆刪除初次見面您好,請問此文連結可以貼至PhotoCap的論壇區去嗎?剛好有人問到此問題。
回覆刪除請便 :P
回覆刪除能幫上您的忙我也很高興
global varible 會被配置到 heap 區
回覆刪除It that true?
剛剛去查了一下, 好像是 DATA segment
回覆刪除沒有查證是我的疏忽 orz
剛剛在 Windows 上用 Visual Studio 測試 C 沒有這個問題耶。
回覆刪除