Upcoming Events
Unite 2010
11/10 - 11/12 @ Montréal, Canada

GDC China
12/5 - 12/7 @ Shanghai, China

Asia Game Show 2010
12/24 - 12/27  

GDC 2011
2/28 - 3/4 @ San Francisco, CA

More events...
Quick Stats
87 people currently visiting GDNet.
2406 articles in the reference section.

Help us fight cancer!
Join SETI Team GDNet!
Link to us Events 4 Gamers
Intel sponsors gamedev.net search:

  Contents

 Overview
 Implications
 Specifications
 Designing With
 Exceptions

 Resources
 Interactions With
 Threads

 Real-Time Systems
 Philosophies
 Potential Pitfalls

 Printable version

 


"Resource allocation is initialization" or Stack-Based Resource Management

This technique, as described Margaret A. Ellis and Bjarne Stroustrup in The Annotated C++ Reference Manual, by Stroustrup in The C++ Programming Language Third Edition and further elaborated on by Meyers in More Effective C++ is well documented. I usually prefer to think of it as Stack-Based Resource Management because it tells me a little more about what is going on and what the goal is.

A great example of this is the Standard C++ Library's auto_ptr() template class, which is specifically designed for this purpose. Here's an example of how it is typically used:

void Func(void) { auto_ptr<MyClass> myClass( new MyClass( ... parameters ... ) ); myClass->Something(); }

There is a number of cool things about this simple example. First, we don't have to worry about deleting the heap object in the case of an exception or normal execution; the auto_ptr's destructor handles this for us. This also means we have one path of execution regardless of whether or not any exceptions occur; either memory exhaustion or those thrown by the constructor of the class. This solution also scales well to having many heap allocated local objects. Even better, we do not have a try block! So we've already simplified the code significantly.

 By using a different kind of smart pointer ( auto_ptr does not necessarily have the best copy semantics for this ) we can also apply this technique to classes which have multiple heap objects as members. This way we can properly handle construction without memory leaks and without a try block. Granted, maybe allocating multiple heap objects is going to cost more in terms of time than the try block initialization is, so maybe its a bit unnecessary from a performance standpoint, but it does make the constructor less cluttered.

Another common use of this technique is for synchronization mechanisms such as critical sections. If a portion of code or an entire routine needs to be synchronized, a simple object can be used to enter the critical section in the constructor and leave the critical section on destruction. I've seen this referred to as a guard or lock.

The fundamental is what Meyer's succinctly describes in More Effective C++ Item 9 - use destructors to prevent resource leaks. I usually tend to think of it as putting code which must execute, regardless of how a block is exited, into the destructor of an object on the stack. In auto_ptr the resource is memory, in a critical section the resource is the lock on the critical section. No doubt you can think of other examples which may be more involved than these simple examples.

This is really one of the most useful aspects of exception handling: stack unwinding. And not only does it make the code easier to read and understand it also can be used to eliminate try blocks, which can help improving application performance.





Next : Interactions with Threads