2012-05-10 132 views
6

我使用VS 2010
當我在調試模式下運行此程序,它會引發堆棧溢出異常,並顯示在行在文件chkstk.asm一個特徵線99
但當我在釋放模式下運行它時沒問題。
此外,如果我將其中一個數組的大小減少到10000,它在調試中效果很好。是什麼原因?堆棧溢出異常

#include <iostream> 

using namespace std; 
int main() 
{ 
    char w[1000001], temp[1000001]; 
    cout<<"Why?"<<endl; 
    return 0; 
} 
+3

您在發佈模式中啓用了哪些優化?編譯器很有可能只是刪除數組。 –

+0

可能的重複[調試堆棧溢出,但不是在發佈](http://stackoverflow.com/questions/5670904/stack-overflow-when-debugging-but-not-in-release) –

+0

你問「什麼是溢出的原因?「或者「行爲在不同構建模式下變化的原因是什麼?」或者是其他東西? –

回答

11

由於堆棧非常小,在大多數系統上大約爲1MB,所以您將使用大型緩衝區溢出堆棧。要解決這個問題,只需像這樣在堆上分配:

#include <iostream> 

using namespace std; 
int main() 
{ 
    char* w = new char[1000001]; 
    char* temp = new char[1000001]; 
    cout<<"Why?"<<endl; 
    delete[] w; 
    delete[] temp; 
    return 0; 
} 
+2

或使用'std :: vector'就像其他人已經建議的! –

5

堆棧很小(〜1MB)。你用這些數組中的大量元素填充它。

如果您需要更多空間,請嘗試在堆上分配(哪些指針會這樣做)。

實現這個的一個好方法是用向量,在堆上其內部存儲的東西:

std::vector<char> w (1000001); 
std::vector<char> temp (1000001); 
4

陣列在自動存儲在棧上分配的。堆棧空間有限。當堆棧空間不足以分配自動變量時,會發生堆棧溢出異常。

如果您需要大的數組,請改爲使用靜態或動態分配。

對於靜態分配,將聲明移至main()以外。

對於動態分配,使用下面的代碼:

char *w = new char[1000001], *temp = new char[1000001]; 
// Work with w and temp as usual, then 
delete[] w; 
delete[] temp; 

最後,可以考慮使用,而不是簡單的陣列標準集裝箱:std::array是一個更好的數組,如果你不需要調整(這是在棧上分配的,並不會解決這個問題); std::string也是取代char陣列的好候選者。

+2

我不認爲'std :: array'會解決他的問題。它將*仍然*在堆棧上分配數據。試試'std :: vector'。 –

+0

@Robᵩ你是對的,它不會!我提到'std :: array'作爲普通數組的替代品,而不是解決這個特定問題的方法。我可以看到這部分答案可能會產生誤導,所以爲了清晰起見我對其進行了編輯。謝謝! – dasblinkenlight

5

你正在堆棧上分配太多東西;可能在調試模式下,堆棧因各種安全檢查而被佔用更多,或故意較小以幫助您在早期檢測到此類問題。無論如何,使數組稍微大一些,即使在發佈模式下也會觸發堆棧溢出(除非編譯器完全優化它們)。

問題的根源在於你不應該在堆棧上分配大的東西,這個堆棧的大小是非常有限的(默認情況下在VC++上爲1MB),並且只能用於小緩衝區/對象。如果您需要大量分配,請在堆上執行(使用new/malloc),最好使用智能指針來避免內存泄漏。