When a constructor of a class allocates memory on the heap, e.g.
class bla
{
private:
double *data;
int size;
public:
bla(int s)
{
size = s;
data = new double [size];
}
~bla()
{
delete[] data;
}
}
and I have a function e.g.
void f(bool huge)
{
bla *ptr;
if (huge)
ptr = new bla(1e10);
else
ptr = new bla(1e2);
//...
delete ptr;
}
What happens if the allocation of ptr = new bla(1e10)
is sucessful (this means, data
and size
allocated) but not the constructor -> he throws exception because 1e10 is to large? I have no memory leak with data = new double [size]
, but have I a memory leak with still existing double *data
and int size
on the heap? Or are they cleared by stack unwinding?
Should I write it better this way?:
void f(bool huge)
{
bla *ptr = 0;
try { ptr = new bla(1e10); }
catch (...) { delete ptr; throw; }
}
and
class bla
{
private:
double *data = 0;
// ... to not have an delete[] on a non-0 pointer
}
Edit:
A bit more elaborated example to illustrate templatetypedefs anwswer:
#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;
}
Whit this example I can nicely see on my machine (Win7 4GB RAM) regarding the ressource monitor, how it goes first inside bla2()
then bla()
but then because because of failure allocating data3
first calls ~bla2()
and then ends (without ~bla()
) in catch(...)
with memory being on baseline like at program start.
When I set the number of data3 elements only 1/4 as much, then all succedes, with expected order of call of constructors and destructors.