Reputation: 4143
I found some interesting behavior in the case of exception when construct an object:
class bookentry
{
public:
bookentry(){
t1.reset(new test1); //0
test1 *t11 = new test1; //1
test2 *t22 = new test2; //2
throw 1; //3
}
protected:
private:
auto_ptr<test1> t1;
auto_ptr<test2> t2;
};
From what I test:
If we throw an exception from test2's constructor (#2), then
If we throw an exception from bookentry's constructor (#3),this time, things will be a litter different: t22 will never be destroyed (neither calling t22's destructor or freeing memory), t11 is same as above
I am just confused with the sentence at #2
test2 *t22 = new test2; //2
It seems that when we throw an exception from class constructor, and new expression will make sure that corresponding delete is called, but any object that fully created via new expression before that exception will be leaked(t11, or t11 and t22 if we throw an exception at #3).
so, if we write codes like below and the 5th object construction failed:
test2 *t2s = new test2[10];
then, it seems it's a litter bit safer:
My questions, is this standard c++ behavior? I just test msvc 2012 and gcc 4.4.6, both looks implementing such mechanism.
Edit TO make my question more clearly:
In some case you need write code like t1.reset(new test1)[see #1 in my codes] in other normal functions. In such case, if an exception is thrown from constructor. How can I reason about the program state? is there any memory leak?
My test make sure these is no memory leaks in such case, but is it standard c++ behavior?
Upvotes: 1
Views: 2196
Reputation: 206636
The rule is simple:
All the objects completely created in that scope will be destroyed
The above rule does not apply to raw pointers pointing to objects allocated on dynamic storage(allocated with new
). They need to be explicitly delete
d. When you use new
you explicitly own the resource management and it is your job to call the delete
to release the resource and the compiler won't do it for you.
Good Read:
Constructor failures - Herb Sutter
Note that the best way to manage resources in C++ is by using RAII and smart pointers. More so in constructors. Instead of using any raw pointers simply wrap them in smart pointers and they will automagically do the resource management for your object in case of such exceptions. You have just experienced this power when you used auto_ptr
in your code example as opposed to the raw pointers.
Upvotes: 3