2012-01-18 151 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