shared_ptr is great...but sometimes auto_ptr is actually better!

— richardwb on Saturday, March 21, 2009 @ 18:04

Modern C++ programming benefits greatly from smart pointers. Smart pointers automate the error-prone process of making sure you have a matching number of new and delete statements. There's even one included in the C++ standard library: std::auto_ptr.

It's not a true general purpose smart pointer, however. For one, it has somewhat unusual transfer-of-ownership semantics:

std::auto_ptr<MyClass> a(new MyClass());
std::auto_ptr<MyClass> b = a;
// a now points to nothing!

This also makes it dangerous to use in containers, as described in Using auto_ptr Effectively. On the other hand, shared_ptr (which will be available in the next C++ standard, C++0x, and is now available in the Boost libraries) is a reference counting smart pointer. It keeps track of the number of references to a particular object, and when there are no more references, it deletes the object. This is safe to use in containers. In fact, you can use shared_ptr pretty much everywhere and you will never have to worry about manually releasing memory again (cycles and threading are pretty much the only major problems).

However, while shared_ptr is a great general purpose smart pointer, auto_ptr has its uses. If you have a function that involves transfer-of-ownership semantics (whether receiving or giving), why not use the smart pointer that perfectly captures those requirements? The 'sources' (creates and then gives away ownership) and 'sinks' (takes ownership) described in the Using auto_ptr Effectively article is a prime example of this. Instead of using comments to specify that the caller of a function must manage the lifetime of the returned object, auto_ptr forces them to manage it (and if they don't, it'll clean itself up anyway). shared_ptr will likely work just as well, but it doesn't capture the semantics.

Another noteworthy reason to use auto_ptr when the semantics are suitable is that while auto_ptr can give away ownership to shared_ptr, shared_ptr cannot give away ownership to auto_ptr or another smart pointer (there is no release() function in shared_ptr).

auto_ptr is on its way to deprecation, but we haven't even seen C++0x yet, so I wouldn't worry too much about it. Its replacement, unique_ptr, will have the same transfer-of-ownership semantics, just implemented in a much safer way, so it'd be worth the effort to get used to using the right smart pointer for the job.

Speaking of which, do you know what scoped_ptr is?

comments powered by Disqus