1110101001
1110101001

Reputation: 5097

C++ - Avoiding memory leak with exceptions

Let's say you have some code like this:

void myFunction()
{
    myClass * mine = new myClass();
    // body of function
    delete mine;
}

If an exception is thrown within the body of the function, the delete will never be called and a memory leak will result. What is the best way to alleviate this, other than using any of the managed pointers within <memory>.

Upvotes: 1

Views: 1437

Answers (4)

Michael Urman
Michael Urman

Reputation: 15905

Your first preference should be not to use new at all. There's nothing in your stripped down example that suggests stack allocation would fail:

void myFunction()
{
    myClass mine;
    // body of function
}

If you do need to allocate on the heap, then prefer to use RAII wrappers (preferring ones in the standard library over custom ones), or try/catch structures.

Upvotes: 1

Slava
Slava

Reputation: 44258

The way to manage it without smart pointer is available, though not recommended:

void myFunction()
{
    myClass * mine = 0;
    try {
        mine = new myClass();
        // body of function
    }
    catch(...) {
        delete mine;
        throw;
    }
    delete mine;
}

Again this method is more error prone (code duplicate etc), RAII is preferred as answered before .

Upvotes: 3

Marius
Marius

Reputation: 2273

Memory Leaks of such kind can easily be avoided by using std::auto_ptr or (with C++11) std::unique_ptr:

#include <memory>

void myFunction()
{
    std::unique_ptr<myClass> mine(new myClass());
    // Use mine as before, mine->foo() or *mine is totally valid
    // The instance of myClass is deleted as soon as the unique_ptr goes out of scope
    // body of function
}

Upvotes: 2

juanchopanza
juanchopanza

Reputation: 227410

Use RAII. There are many ways to do this, the best would be to use tried and tested solutions such as smart pointers like std::unique_ptr<myClass> or boost::scoped_ptr<myClass>.

If you want to go through the exercise of implementing a RAII solution yourself, it could be in the form of a scope guard:

struct guard
{
  myClass* ptr;
  guard(myClass* p) : ptr(p) {}
  ~guard() { delete ptr; }
  guard(const guard&) = delete;
  guard& operator=(const guard&) = delete;
};

Note that RAII requires that the code be in a try block at some level.

Upvotes: 12

Related Questions