Cleaning Resources Automatically

HelllllloW everybody!!!

Finally I am back, after 7 months, from a crazy trip in South America! Where I got robbed at gun-point, and denied access to USA (wanted to consult there), saw amazing views and creatures, among other stories, but it’s not the place to talk about them :) Maybe if you insist I will post once about it.

<geek warning>
Honestly, I freaked out in the trip without a computer (bits/assembly/compiler),  so all I could do was reading and following many blogs and stuff.
</geek warning>

I even learned that my post about the kernel DoS in XPSP3 about the desktop wallpaper weakness became a CVE. It seems MS has fixed it already, yey.

And now I need to warm up a bit, and I decided to dive into C++ with an interesting and very useful example. Cleaning resources automatically when they go out of scope. I think that not many people are aware to the simplicity of writing such a feature in C++ (or any other language that supports templates).

The whole issue is about how you destroy resources, I will use Win32 resources for the sake of example. I already talked once about this issue in C.

Suppose we have the following snippet:

HBITMAP h = LoadBitmap(...);
if (h == NULL) return 0;
HBITMAP h2 = Loadbitmap(...);
if (h2 ==  NULL) {
   DeleteObject(h);
   return 0;
}
char* p = (char*)malloc(1000);
if (p == NULL) {
   DeleteObject(h2);
   DeleteObject(h);
   return 0;
}

And so on, every failure handling in the if statements we have to clean more and more resources. And you know what, even today people forget to clean all resources, and it might even lead to security problems. But that was C times, and now we are all cool and know C++, so why not use it? One book which talks about these issues is Effective C++, recommended.

Also, another problem with the above code is while an exception is being thrown in the middle or afterward, you still have to clean those resources and copy/paste some lines, which makes it prone to errors.

Basically, all we need is a nice small class which will be called AutoResource that holds the object itself and will manage it. Personally, it reminds me auto_ptr class, but it’s way less permissive. You will be only able to initialize and use the object. Of course, it will be destroyed automatically when it goes out of scope.
How about this code now:

AutoResource<HBITMAP> h(LoadBitmap(...));
AutoResource<HBITMAP> h2(LoadBitmap(...));
char* p = new char[1000]; // If an exception is thrown, all objects initialized prior to this line are automatically cleaned.

Now you can move on and be totally free of ugly failure testing code and not worry about leaking objects, etc. Let’s get into details. What we really need is a special class that we can change the behavior of the CleanUp()  method according to its object’s type, that’s easily possible in C++ by using a method specialization technique. We will not let to copy or assign to the class. We want a total control over the object, therefore we will let the user to get() it too. And as a type of defense programming, we will force the coder to implement a specialized CleanUp() in a case he uses the class for new types and forgets to implement the new CleanUp code; By using compile time assertion (I used this trick from Boost). Also, there might be a case where the constructor input is NULL, and therefore the constructor will have to inform the caller by throwing an exception, download and check out the complete code later.

template <class T> class AutoResource {
public:
   AutoResource(T t) : m_obj(t) { }

   void CleanUp()
   {
      // WARNING:
      // If the assertion occurred you will have to specialize the CleanUp with the new type.
      BOOST_STATIC_ASSERT(0);
   }

   ~AutoResource()
   {
      CleanUp();
      m_obj = NULL;
   }
   T get() const
   {
      return m_obj;
   }
private:
   T m_obj;
};

//Here we specialize the CleanUp() for the HICON resource.
template<> void AutoResource<HICON>::CleanUp()
{
   DestroyIcon(AutoResource<HICON>::m_obj);
}

You can easily add new types and enjoy the class.  If you have any suggestions/fixes please leave a comment!

Download complete code: AutoResource.cpp.

Thanks to Yan Michalevsky for helping with the code!

P.S – While compiling this stuff, I found a crash in the Optimization Compiler of VS2008 :)  lol.

8 Responses to “Cleaning Resources Automatically”

  1. James Lawler says:

    You might be interested in Petru Marginean’s ScopeGuard, which is a refinement of this very idea.

    You can read Andre Alexandrescu’s <a href=”http://www.ddj.com/cpp/184403758″>article on the subject</a> for a good introduction.

  2. Your trip sounds awesome! ;-) What did you do?

    The RAII idiom (resource acquisition is initialization) you are describing in your post is well known and well documented. There are lots of articles about the subject and at least one major generic implementation in the form of boost::shared_ptr. Don’t be confused by the seemingly narrow focus on reference counting – that is not everything you can use it for. See here for examples:
    http://www.boost.org/doc/libs/1_40_0/libs/smart_ptr/sp_techniques.html

    Anyways, very useful (I’d say essential) technique for writing robust C++ code. Especially in the face of exceptions. Thank you for the article.

    cheers,

    Sören

  3. djTeller says:

    Nice article, remind me of <auto_ptr> like your said.

    Using template wrapping that clean up is generally a great idea and I’ll adopt it!

    Thanks!

    – T

  4. lorg says:

    Heya,
    Welcome back!

    You can improve on this by using ‘substitution failure is not an error’, and maybe even specify which cleanup function to call during compile time.

    See http://cpptalk.wordpress.com/2009/09/11/substitution-failure-is-not-an-error-1/

  5. arkon says:

    James – Yeah, I was wondering whether to talk about this book, it’s a very good one.
    Sören – Thanks, I will check it out, though I think I am familiar with it.
    lorg – Thanks man :) Nice idea, I will see if it’s possible and update.

  6. declan says:

    C++ has had pure virtual functions for ages … make CleanUp() a pure virtual function and then all derived classes must implement CleanUp()

    virtual void CleanUp() = 0;

  7. […] important and useful classes I have used in my code. Also the AutoResource class I posted about here, is another type of a smart pointer. I fell in love with smart pointers as soon as I learnt about […]

  8. nids says:

    Why don’t you use a second template parameter: the AutoResourceTraits?
    It can contain a couple of static methods: destroy and isOk (the last one used by the destroy to check if the destruction can be done in a safe way).
    At this point you can just write the trait for each type that you need and use a typedef:

    tamplate
    class AutoResourceTraits { … };

    typedef AutoResource<Blah, AutoResourceTraits > AutoBlah;

    BTW, the get method could return a reference to m_obj and not a copy of m_obj (in general for HANDLE at simila it is exactly the same but for complex objects it is not).

Leave a Reply