RAII – Resource Acquisition Is Initialization

Resource Acquisition is Initialization (or RAII for short, usually pronounced by simply spelling out the letters R-A-I-I) is a programming technique where we make sure that resources are cleaned up when they are no longer needed by tying a resource to an object. The resource is kept as long as the object is alive and automatically released when the object is destroyed.

The resource that is being managed can be a segment of memory, a file handle, a network socket, a database handle or anything else which there is just a limited number of in the system and which we need to make sure we close properly after we are done with it.

The way RAII works is that we tie the resource to a class. When an instance of the class is created then the constructor of the object’s class is called to create the resource (or passed the resource to be managed). When the object is later destroyed (by going out of scope) then the destructor will automatically be called and here we write the code to release the resource again.

The name is somewhat difficult and controversial, some have suggested instead calling it Scope-Bound Resource Management but this has so far not been too successful.

I think an example of what I mean is necessary here. In the example below is a segment of memory allocated (using new[]) in the constructor of the File class and the memory is released again (using delete[]) in the destructor. The neat thing here is that the destructor will automatically be called when the object goes out of scope, as is done when the function main() in the example exits.

Notice: this is only done automatically for you if the File object is allocated as a local object, this is one of the reasons why you should never use new or delete.

The benefits of RAII is that it creates:

  • exception safety: a stack object will be destroyed at the end of the enclosing scope,  also if an exception is thrown from the code after the object is created.
  •  good locality: the code for allocating the resource is in the same class as the code for releasing the resource again.
  • encapsulation: the managed resource is located inside the owning class and not accessible outside of it.

Because of its benefits is RAII used extensively throughout the standard library classes.

As an example, the following code is using old C functions to write data to a text file NOT using RAII.

In the example above we didn’t use RAII to hold on to the resource (which in this case is the file handle FILE* f). This makes the code not exception safe, if anyone would later add a function call after the file has been opened and this method throws an exception then the call to fclose will not be executed at all, leaving the file opened and locked.

A better example is to instead use the standard library to open and write to the file:

in this example does the instance of the standard library class std::ofstream which we create on the first line hold on to the file resource and when the object goes out of scope when the function ends then the file will be closed automatically for us. Notice how much shorter and cleaner this code becomes. We don’t have to worry about closing the file since this is done for us.

References

  1. Stroustrup: Why doesn’t C++ provide a “finally” construct?

 

Facebookgoogle_pluslinkedinmail

Leave a Reply

Your email address will not be published. Required fields are marked *