C ++ bad_alloc异常

时间:2012-01-18 23:24:02

标签: c++ windows exception

我试图捕获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)。 为什么会这样?

修改 我现在得到异常,但我应该证明在抛出异常之前使用了析构函数。我该怎么做?

3 个答案:

答案 0 :(得分:8)

在您开始动态分配对象之前,问题就出现了。如果运行附带调试器的程序,您将看到程序因堆栈溢出而终止。为什么呢?

Obj* ptr[1000000];

您无法声明具有自动存储持续时间的大型对象。输入main时,它会尝试为此对象分配堆栈空间,但无法执行此操作,从而导致堆栈溢出结构化异常被抛出。您的应用程序不处理此异常,因此运行时将终止该程序。

但请注意,程序永远不会调用Obj析构函数。使用new动态分配对象时,您有责任使用delete销毁它。由于您没有调用delete来销毁您创建的对象,因此它们永远不会被销毁。

如果您要使用std::vector<std::unique_ptr<Obj>>代替(或者,就此而言,仅仅是std::vector<Obj>),您会看到每个完全创建的{{}都会调用析构函数1}}对象。

答案 1 :(得分:4)

请记住,您正在尝试使用ptr数组在堆栈中存储一个非常大的数组...很可能您的问题是您已经溢出为您分配的堆栈的默认大小operator new之前的应用程序可能因内存不足而失败。

答案 2 :(得分: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;
}

[jhumphreys@suoserv ~]$ g++ so2.cpp
[jhumphreys@suoserv ~]$ ./a.out
EXCEPTIONDone.
[jhumphreys@suoserv ~]$