简体   繁体   中英

c++ free memory allocation in constructor when facing exception

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

  1. t1 : will be fully destroyed, ie t1's destructor will called, and memory will be freed.
  2. t11 : will never be destroyed (neither calling t11's destructor or freeing memory).
  3. t22 : this is funny part, t22's destructor will not be called which is right, but t22's memory will be freed!

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:

  1. the already constructed objects will be destroyed,
  2. the memory will be freed.

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?

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM