C++ RAII: Resource Acquisition Is Initialization

Help us to keep this website almost Ad Free! It takes only 10 seconds of your time:
> Step 1: Go view our video on YouTube: EF Core Bulk Extensions
> Step 2: And Like the video. BONUS: You can also share it!

Remarks

RAII stands for Resource Acquisition Is Initialization. Also occasionally referred to as SBRM (Scope-Based Resource Management) or RRID (Resource Release Is Destruction), RAII is an idiom used to tie resources to object lifetime. In C++, the destructor for an object always runs when an object goes out of scope - we can take advantage of that to tie resource cleanup into object destruction.

Any time you need to acquire some resource (e.g. a lock, a file handle, an allocated buffer) that you will eventually need to release, you should consider using an object to handle that resource management for you. Stack unwinding will happen regardless of exception or early scope exit, so the resource handler object will clean up the resource for you without you having to carefully consider all possible current and future code paths.

It's worth noting that RAII doesn't completely free the developer of thinking about the lifetime of resources. One case is, obviously, a crash or exit() call, which will prevent destructors from being called. Since the OS will clean up process-local resources like memory after a process ends, this is not a problem in most cases. However with system resources (i.e. named pipes, lock files, shared memory) you still need facilities to deal with the case where a process didn't clean up after itself, i.e. on startup test if the lock file is there, if it is, verify the process with the pid actually exists, then act accordingly.

Another situation is when a unix process calls a function from the exec-family, i.e. after a fork-exec to create a new process. Here, the child process will have a full copy of the parents memory (including the RAII objects) but once exec was called, none of the destructors will be called in that process. On the other hand, if a process is forked and neither of the processes call exec, all resources are cleaned up in both processes. This is correct only for all resources that were actually duplicated in the fork, but with system resources, both processes will only have a reference to the resource (i.e. the path to a lock file) and will both try to release it individually, potentially causing the other process to fail.



Got any C++ Question?