Resource Acquisition Is Initialization Article Index for
Resource
Shopping
Acquisition
Website Links For
Resource
 

Information About

Resource Acquisition Is Initialization




Resource Acquisition Is Initialization (often referred to by the acronym '''RAII'''; sometimes also used as '''Resource Initialization Is Acquisition''' or as the acronym '''RIIA''') is a popular programming technique in C++ and D . The technique combines acquisition and release of resources with initialization and uninitialization of Variable s.

The acquisition is bound to the construction (initialization) whereas the release is bound to the destruction (uninitialization) of the variable. Since a destructor of an automatic variable is called when leaving its scope, it can be guaranteed that the resource is released as soon as the variable's life time ends. This is also true for cases when an exception occurs. Thus, RAII is a key concept for writing Exception-safe code (Sutter 1999).


EXAMPLE


Here is an example (in C++ ):

class LogFile
{
public :
  • fileName)

  • : m_file( OpenFile(fileName) ) // initialize data member with the file handle

{ if( m_file == INVALID_HANDLE ) throw FileFailedToOpen(); } // handle errors automatically

~LogFile() { CloseFile(m_file); }

  • logLine) { WriteFile( m_file, logLine ); }


private :
FILE_HANDLE m_file;

// avoid copying by declaring a private but unimplemented copy-constructor
// and assignment operator
LogFile (const LogFile&);
LogFile& operator= (const LogFile&);
};

This simple RAII class can be used like this :

bool functionA()
{
LogFile log("Output log of functionA");

log.write("fun Step5 succeeded");

// The function can throw exceptions and return
// without worrying about closing the log:
if( ... )
throw FunctionAFailure(); // or return false

return true;
}

Without using RAII, each function using an output log would have to manage the ''FILE_HANDLE'' resource explicitly.
For example, the equivalent implementation of ''functionA'' without using RAII would be:

bool functionB()
{
FILE_HANDLE log;
try {
log = OpenFile("Output log of functionB");

// EXTRA CODE: explicit error checking:
if( log == INVALID_HANDLE )
return false;

WriteFile( log, "fun Step5 succeeded" );

// if the function needs to check for an error and abort accordingly:
if( error ) {
// EXTRA CODE: release the acquired resources
CloseFile(log);
return false; // or throw an exception
}

// EXTRA CODE: the resource needs to be closed explicitly
CloseFile(log); // explicitly release the resource

return true;
}
catch (...) {
// An exception was thrown during the execution of the function

// Time to cleanup the resources
CloseFile(log);

// Now handle the exception, or re-throw it, or return false
}
}

The essence of the RAII idiom is that the class ''LogFile'' encapsulates the management of an operating-system resource, the ''FILE_HANDLE''. It guarantees that the resource will properly be disposed of at function exit. Furthermore, ''LogFile'' instances guarantee that a valid log file is available (by throwing an exception if the file could not be opened).

There's also a big problem in the presence of exceptions: in ''functionB'', if more than one resource were allocated, but an exception was to be thrown between their allocations, there's no general way to know which resources need to be released in the final ''catch'' block - and releasing a not-allocated resource is usually a bad thing. RAII takes care of this problem; the automatic variables are destructed in the reverse order of their construction, and an object is only destructed if it was fully constructed (no exception was thrown inside its constructor). So ''functionB'' can never be as safe as ''functionA'' without special coding for each situation - like checking for invalid-default values, or nesting try-catch blocks.

This frees ''functionA'' from explicitly managing the resource as would otherwise be required. When several function use ''LogFile'', this simplifies and reduces overall code size, and helps ensure program correctness.

Languages that do not support RAII, such as Java, provide an alternative solution to ensure that a resource will be released, with ''try-finally'' blocks. This allows to write correct code, but does not fully encapsulate the management of resources, as each and every function using ''LogFile'' may have to explicitly demand the destruction of the log file with a ''try-finally'' block.


TYPICAL USES


The RAII technique is typically used for controlling thread locks in multi-threaded applications. Another typical example of RAII is file operations, e.g. the C++ Standard Library 's file- Stream s. An input file stream is opened in the object's constructor, and it is closed upon destruction of the object. Since C++ allows objects to be allocated on the Stack , C++'s scoping mechanism can be used to control file access.

RAII is also used (as shown in the example above) to ensure exception safety. It is a very useful technique to avoid resource leaks without giving too much work to the developer, and is widely used in the software industry.

Furthermore the ownership of dynamically allocated memory (with new) can be controlled with RAII technique. For this purpose, the C++ Standard Library defines Auto_ptr .


LIMITATIONS


RAII is easiest to use in languages that automatically call the destructor for local objects when they go out of scope (e.g. C++ ). Where this is not the case, the programmer must assure that the destructor is called for local objects as they go out of scope.

In some garbage-collected languages (e.g. Java or C# ) the garbage collector is responsible for the eventual destruction of local objects and it is thus impossible to know when the destructor will be called; to use RAII in such languages the programmer must define and call a finalization routine. However the latest version of C# includes the ''using'' statement which makes RAII much easier, see: Wikibooks:C Sharp Programming/Object Lifetime . A similar facility is expected to be included in the 2006 release of VB.NET.

In other garbage collected languages (such as D ), class instances can be declared such that when they go out of scope, the destructor will get called, thereby supporting RAII.


REFERENCES



EXTERNAL LINKS