2013-02-28 76 views
0

我有一個小程序,用C++編寫,包含一個大型數組的類。這個類看起來像這樣:爲什麼我的程序在構造函數中使用fread時崩潰?

class Test 
{ 
public: 
    Test(); 
    ... 
private: 
    int myarray[45000000]; 
}; 

現在,這個數組從文件讀入。我想直接與構造函數做到這一點,而不是打擾任何額外的功能。該數組只需要一次讀入,之後不會再改變。它具有指定的確切大小。

我的構造是這樣的:

Test() 
{ 
    memset(myarray, 0, sizeof(myarray)); 
    FILE* fstr = fopen("myfile.dat", "rb"); 
    size_t success= fread(myarray, sizeof(myarray), 1, fstr); 
    fclose(fstr); 
} 

使用Visual Studio 2012旗艦版:當試圖啓動一個使用這個類的程序,它與「APPCRASH」崩潰只要創建類,和當試圖對其進行調試時(我幾乎不知道),告訴我該錯誤是堆棧溢出。

這一切的奧祕在於,在我以前的版本中,myarray是一個靜態變量,我不得不調用靜態函數來設置它,一切都很順利。但試圖將其轉換爲構造函數,盡我所能,我所有的嘗試都失敗了。

那麼我在這裏做錯了什麼?

+1

您的課程對於堆棧太大了。嘗試在堆中分配數組,而不是在堆棧中分配數組。 – Nick 2013-02-28 13:40:57

回答

3

,所以你可能做到這一點在你的主(或其他地方)

int main() 
{ 
    Test t; // Hello StackOverflow 
} 

你需要的是給它分配在堆上:

int main() 
{ 
    Test* t = new Test; 
    delete t; 
} 

它沒有靜態變量,因爲崩潰靜態變量不在堆棧上分配

+4

更好的是,將'myarray'改成一個動態數組(最好是'std :: vector ',所以你不需要自己處理任何內存管理)。然後'Test'的用戶不會有任何死亡陷阱可以避免。 – 2013-02-28 13:49:29

+0

@MikeSeymour,我同意。但問題是如何在這種特殊情況下避免SO。 – 2013-02-28 13:57:35

+2

確實,這是個問題。在我看來,最好的答案是重新設計班級,以免造成SO,而不是要求班級的用戶以非常規方式使用它。 – 2013-02-28 14:00:53

3

即使您的int是2字節的最小大小,您的數組也會使用大約86MB的內存。典型的最大堆棧大小爲1MB。如果您的Test對象的存儲已分配到堆棧上,則很容易溢出。您需要動態分配數組,或者不要一次將所有數據全部加載到內存中。更好的是,使用一個標準容器,爲其元素使用動態分配,比如`std :: vector。

3

此聲明在類:

int myarray[45000000]; 

試圖分配每個INT 45000000 * 4個字節(假定32位)=的存儲器180MB。沒有辦法你的堆棧將支持。您需要重新設計應用程序以更改加載文件的方式。

相關問題