我试图捕获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)。 为什么会这样?
修改 我现在得到异常,但我应该证明在抛出异常之前使用了析构函数。我该怎么做?
答案 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 ~]$