2012-01-18 152 views
4

我試圖捕捉bad_alloc異常,以證明使用了析構函數。C++ bad_alloc異常

這裏是我的對象:

#include "Obj.h" 
#include<iostream> 
using namespace std; 

Obj::Obj() { 
d = new double[200000000]; 
} 
Obj::~Obj() { 
cout << "destroyed \n"; 
} 

和主要方法:

#include "Obj.h" 
#include <iostream> 
using namespace std; 
int main(){ 
Obj* ptr[1000000]; 
try{ 
    for(int i=0; i<1000; i++){ 
     ptr[i] = new Obj(); 
    } 
} catch(bad_alloc){ 
    cout<<"EXCEPTION"; 
} 
} 

而是捕捉異常的,我的程序會停止並試圖尋找解決方案在線(Windows)中。 這是怎麼回事?

編輯 我現在越來越例外,但我要證明,析構函數使用之前拋出異常。我應該怎麼做?

+1

在線解決方案?那是什麼? – 2012-01-18 23:26:12

+0

在Visual Studio中聯機命名的解決方案我猜。 – WebMonster 2012-01-18 23:27:55

+2

@VJovic:在Windows中,當程序導致Windows能夠檢測到的某些類錯誤時,會彈出一個對話框,詢問您是否希望Windows在線查找解決方案(可能程序存在錯誤並且存在已知的修復程序它)。 – 2012-01-18 23:29:58

回答

8

在開始動態分配對象之前就會出現問題。如果在附加了調試器的情況下運行該程序,則會看到程序因堆棧溢出而終止。爲什麼?

Obj* ptr[1000000]; 

您不能聲明自動存儲持續時間這麼大的對象。當輸入main時,它會嘗試爲該對象分配堆棧空間,但不能這樣做,從而導致引發堆棧溢出結構化異常。您的應用程序不處理此異常,因此運行時會終止程序。

但是,請注意,Obj析構函數將永遠不會被您的程序調用。當您使用new動態分配對象時,您有責任使用delete銷燬該對象。由於您不曾致電delete銷燬您創建的對象,因此不會銷燬它們。

如果你使用,也就是說,一個std::vector<std::unique_ptr<Obj>>而不是(或者,對於這個問題,只是一個std::vector<Obj>),你會看到,析構函數被調用每一個完全建立Obj對象。

+0

謝謝。我現在得到例外。請參閱問題更新。 – Dragos 2012-01-18 23:39:40

+1

我以爲Windows上的默認堆棧分配爲1Mb,因此理論上這應該適合...雖然可能不與其他所有東西。 – Benj 2012-01-18 23:42:38

+0

'std :: vector >'會爲C++ 03生成一個編譯器錯誤,大多數編譯器仍然依賴它。 – 2012-01-18 23:43:03

4

請記住,您正試圖在您的ptr陣列上存儲一個非常大的陣列堆棧......最有可能的問題是您已經溢出爲您的應用程序分配的堆棧的默認大小operator new能夠因內存不足而發生異常。

+0

分配空間爲1000000,然後只使用1000沒有多大意義。更不用說每個對象都會嘗試在'new'中分配1.6GB(200M * 8) - 我不確定你甚至能夠分配其中的一個。 – 2012-01-18 23:40:37

1

我將所有的代碼粘貼到一個文件中,稍微增加了整型常量,完成了Obj的類定義,並用一些調試重新編譯了代碼。在64位unix服務器上,當它嘗試執行Obj構造函數時,它會正確輸出「異常」。

#include<iostream> 
using namespace std; 

struct Obj { 
Obj() { 
d = new double[20000000000000000LL]; 
} 
~Obj() { 
cout << "destroyed \n"; 
} 

double* d; 
}; 

int main(){ 
Obj* ptr[1000000]; 
try{ 
    for(int i=0; i<1000; i++){ 
     ptr[i] = new Obj(); 
     cout<<"bah!"<<endl; 
    } 
} catch(bad_alloc){ 
    cout<<"EXCEPTION"; 
} 
cout<<"Done."<<endl; 
} 

[[email protected] ~]$ g++ so2.cpp 
[[email protected] ~]$ ./a.out 
EXCEPTIONDone. 
[[email protected] ~]$ 
+0

有沒有辦法在Windows上獲得例外? – Dragos 2012-01-18 23:37:49

+0

我沒有可用的視覺工作室環境 - 但我會假設如果您運行的是在沒有安裝visual studio及其調試工具的計算機上創建的可執行文件,那麼您會看到預期的輸出當你編寫程序時。從內存中我很確定,調試器功能是一個開始安裝開發工具後啓用的窗口的插件。 – 2012-01-18 23:38:50

+0

它與過度保護無關。當您用完堆棧空間時,堆棧空間用完。 – 2012-01-18 23:41:29