Reputation: 8591
So I was looking at this question Memory Allocation Exception in Constructor where my boss states in his beautiful answer that the destructor will not be called.
Which makes me wonder,
If I were to write
struct XBase
{
int* a;
char* b;
float* c;
XBase() : a(nullptr), b(nullptr), c(nullptr) {}
~XBase()
{
delete[] a; delete[] b; delete[] c;
}
};
and
struct X : XBase
{
X() {
a = new int[100];
b = new char[100];
c = new float[100];
}
}
Then, if the allocation of c
fails (with an exception being thrown), then the destructor of XBase
would be called, since the base class has been constructed.
And no memory leak?
Am I correct?
Upvotes: 11
Views: 171
Reputation: 8141
Just to have a formal version here to back up the claims,
§ 15.2/2
An object of any storage duration whose initialization or destruction is terminated by an exception will have destructors executed for all of its fully constructed subobjects [...].
Upvotes: 0
Reputation: 15532
You are right; this will work, because:
X
constructor body is executed, XBase
is already constructed, and its destructor will be called.delete
or delete[]
on null pointers is perfectly valid, and does nothing.So, if the allocation of a
, b
or c
fails, the destructor of XBase
will deallocate everything.
But, obviously, this design makes you write much more code that needed, since you can simply use std::vector
or std::unique_ptr<T[]>
.
Upvotes: 8
Reputation: 196
If you're concerned about the memory allocation failing, I would put it in a separate method, like a Build
or Create
. You could then let the destructor handle it if it has been initialized (but definitely check pointer before blindly delete
-ing.
Another solution is smart pointers, which are not designed to fit this case necessarily, but do automatically deallocate their contents.
Upvotes: -1