开发者

Catching exceptions in constructor

开发者 https://www.devze.com 2023-04-12 10:14 出处:网络
The following example leave a possible memory leak because the destructor doesn\'t run for the object on which the exception is handled during its constructor is run. where do i handle this memory lea

The following example leave a possible memory leak because the destructor doesn't run for the object on which the exception is handled during its constructor is run. where do i handle this memory leak?

#include <exception>

class MyClass {

public:
       MyClass() 
       {
           c = new char[5];
           thro开发者_开发百科w std::runtime_error("test");
       }

      ~MyClass ()
       {
           delete[] c;
       }

private:
    char *c;
};

int main()
{
    try 
    {
        MyClass Obj;

    } 
    catch (std::runtime_error)
    {

    }
}


Catch the exception in the constructor, tidy up (deallocate your memory), then throw the exception without the memory leak.


You are better off using RAII, smart pointer in this case to be specific.

Or alternatively, You can use Two Phased Construction strategy.

You could always use enclosing try-catch blocks inside constructor body and explicitly call delete for all those resources which you dynamically allocated but think of the scenario where you have n number of resources being dynamically allocated,it becomes really messy to explicitly keep track of each resource that you need to deallocate in the catch, in such a scenario, RAII provides you the best solution because then each resource implicitly takes care of its own deallocation and you do not need to have the overhead of keeping track of each resource.

boost::scoped_ptr or std::tr1::scoped_ptr are apt for this scenario instead of any raw pointers.


One way is to throw the conditional exception in the beginning of the constructor and then allocate the memory.

  MyClass() 
  {
     if(<condition>)
       throw std::runtime_error("test");
     c = new char[<SIZE>];
  }

Other way is to use special try-catch() syntax enclosing the constructor:

MyClass() 
  try {
    c = new char[5];
    throw std::runtime_error("test");;
  }
  catch(std::runtime_error e) {
    delete[] c;
  }

Demo.


You can catch the exception in the constructor body, do what cleanup you need, then rethrow the exception with throw;

That said, exceptions and manual handling of memory don't go nicely together. You will be much better off using an object that automatically manages the memory for the c member (e.g std::string, std::vector<char>, std::unique_ptr<char[]> etc). You really only need to manage memory explicitly if you are writing a class like one of the above whose purpose is exactly to look after that memory.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号