3

I'm looking for a way to ensure that an object that is executed on the heap is ALWAYS deallocated when I'm done with it.

I know that if it's allocated on the stack, I can use RAII to ensure it will be taken care of - unfortunately, this won't work for me (at least directly) because the object in question is actually created by calling an api function, which then returns a pointer to the object it creates on the heap.

So, conceptually, what I want to do is something like:

TheApi::ApiObject* p_myObj = TheApi::createAnApiObj();
try
{
    doStuffWithMyObjThatMayError(p_myObj);
}
finally
{
    delete p_myObj;
}

The only thing I can think of to do would be to make some sort of dummy cleanup class, and create an instance of that on the stack:

class MegaMaid
{
private:
    TheApi::ApiObject* toFree;
public:
    MegaMaid(TheApi::ApiObject* toFree)
    {
        this->toFree = toFree;
    }

    ~MegaMaid()
    {
        delete toFree;
    }
};

void doStuff()
{
    TheApi::ApiObject* p_myObj = TheApi::createAnApiObj();
    TheApi::ApiObject* p_myObj;
    MegaMaid cleaner(p_myObj);
    doStuffWithMyObjThatMayError(p_myObj);
}

Is there a better way to accomplish this? Or is this the accepted solution?

trincot
  • 317,000
  • 35
  • 244
  • 286
Paul Molodowitch
  • 1,366
  • 3
  • 12
  • 29

2 Answers2

6

That "dummy class" is known as "smart pointer". You should check out std::auto_ptr or boost::shared_ptr. They provide exactly what you look for.

Nam Nguyen
  • 1,765
  • 9
  • 13
6

You can still use RAII on pointers returned by functions. You can use smart pointers (which is exactly what the dummy class you are describing is) like this:

std::unique_ptr<TheApi::ApiObject> p_myObj(TheApi::createAnApiObj());
Seth Carnegie
  • 73,875
  • 22
  • 181
  • 249
  • Hmm, thanks... that seems exactly like what I was looking for! – Paul Molodowitch Aug 31 '11 at 03:23
  • So I may have spoken a little hastily... in my particular case, you're actually supposed to call a close method on ApiObject, AND delete it... I know, poor design on the api side, this should be handled in the destructor for ApiObject... what's the standard way for handling this situation? – Paul Molodowitch Aug 31 '11 at 03:32
  • 2
    @PaulMolodowitch Use a custom deleter. `std::unique_ptr` actually is `std::unique_ptr>` where `std::default_delete::operator()(T* p);` does `delete p;`. You can use a `std::unique_ptr` to do what you want come destruction time. – Luc Danton Aug 31 '11 at 03:50