【发布时间】:2013-12-13 20:41:40
【问题描述】:
当类的构造函数在堆上分配内存时,例如
class bla
{
private:
double *data;
int size;
public:
bla(int s)
{
size = s;
data = new double [size];
}
~bla()
{
delete[] data;
}
}
我有一个功能,例如
void f(bool huge)
{
bla *ptr;
if (huge)
ptr = new bla(1e10);
else
ptr = new bla(1e2);
//...
delete ptr;
}
如果ptr = new bla(1e10) 的分配成功(这意味着data 和size 已分配)但不是构造函数-> 因为1e10 太大而引发异常,会发生什么情况?我没有data = new double [size] 的内存泄漏,但是我是否在堆上仍然存在double *data 和int size 的内存泄漏?还是通过堆栈展开清除它们?
我应该这样写更好吗?:
void f(bool huge)
{
bla *ptr = 0;
try { ptr = new bla(1e10); }
catch (...) { delete ptr; throw; }
}
和
class bla
{
private:
double *data = 0;
// ... to not have an delete[] on a non-0 pointer
}
编辑:
一个更详细的例子来说明模板类型定义答案:
#include <iostream>
using namespace std;
class bla2
{
private:
double *data;
public:
bla2 ()
{
cout << "inside bla2 constructor, enter to continue";
cin.get();
data = new double [2*256*256*256];
}
~bla2 ()
{
cout << "inside bla2 destructor, enter to continue";
cin.get();
delete[] data;
}
};
class bla
{
private:
bla2 data1;
double data2[2*256*256*256];
double *data3;
public:
bla ()
{
cout << "inside bla constructor, enter to continue";
cin.get();
data3 = new double [8*256*256*256]; // when only 1/4 as much -> then all success
}
~bla ()
{
cout << "inside bla destructor, enter to continue";
cin.get();
delete[] data3;
}
};
void main()
{
bla *a;
cout << "program start, enter to continue";
cin.get();
try { a = new bla; }
catch (...) { cout << "inside catch, enter to continue"; cin.get(); exit(EXIT_FAILURE); }
cout << "success on a, enter to continue";
cin.get();
delete a;
}
这个例子我可以很好地在我的机器(Win7 4GB RAM)上看到关于资源监视器,它是如何首先进入bla2() 然后bla() 但是由于分配失败data3 第一次调用~bla2()然后在catch(...) 中结束(没有~bla()),内存处于基线状态,就像程序启动时一样。
当我将 data3 元素的数量设置为只有 1/4 时,所有成功,构造函数和析构函数的调用顺序符合预期。
【问题讨论】:
标签: c++ exception memory-leaks stack-unwinding