Cogs and Levers A blog full of technical stuff

RAII for C++

Introduction

In programming, RAII stands for “Resource Acquisition is Initialization” and it’s an idiom or technique established by Bjarne Stroustrup to ease resource allocation and deallocation in C++.

Common problems have been when an exception is thrown during initialization, any memory associated during construction (or underlying resources) aren’t released, creating memory leaks in applications.

The Idea

The basic premise is that resource allocation is to be performed in the constructor of your class. Release of the resources occurs in your destructor. The example given on the Wikipedia page deals with holding a lock/mutex for a given file. When execution leaves the scope of the code (whether it be from premature termination of an exception or from the code naturally exiting), the destructors run to release the file handle and lock.

The concept is a great way to not only clean up your code (as all of the “if !null” code is now redundant) but it’s a great safe-guard that you can almost be absent minded about.

It’s important to note that this idiom doesn’t allow you to ignore good exception handling practice. You’re still expected to use exception handling in your code, this will just ensure that your cleanup/release code is executed as expected.

An Implementation

Implementing this idea into your own code is really quite simple. If you have a resource (handle) that you’re managing manually, wrap it in a class.

  • Ensure the constructor takes the handle in
  • Release the handle in the destructor

When working with OpenGL textures, I use a very small class that allows me to handle the resource cleanup, it just managed the generated texture id. When the class falls out of scope or there’s a failure during initialization, the texture is cleaned up.

class texture {
  public:
    // manage the generated texture id
    texture(const GLuint t) : _reference(t) { }
    
    // cleanup of the allocated resource
    virtual ~texture(void);

    // provide access to the reference
    const GLuint reference() const { return _reference; }

  private:
    GLuint _reference;
};

texture::~texture(void) {
  // only run if we have something to clean up
  if (this->_reference != 0) {
    // clear out the texture  
    glDeleteTextures(1, &this->_reference);
    this->_reference = 0;
  }
}

Strictly speaking, the constructor should probably do the generation of the texture itself. Where I’m loading the texture is in another managed object of itself. Most importantly, if an exception is thrown during initialization, this class will remove anything allocated to it (if it did allocate).

It should be mentioned that there are lots of extra attributes we can pile into RAII style classes. There’s a really good write up (in depth) here.

Conclusion

RAII is a great idea to implement into your own classes. The more of this you can practice, the more exception-safe your code will become . . . from car accidents.