What are the advantages and disadvantages of using auto pointers (auto_ptr), compared to ordinary pointers? I've heard it does automatic releasing of memory but how come it is not used often?
Smart pointers are used often in C++, though perhaps not as often as they should be. The std::auto_ptr
has a few problems (you can't use it in Standard Library collections, for example), but there are many others. The most popular of these are the ones that come with the Boost library, and which will be part of the next C++ standard - you should take a look.
Note that smart pointers are mostly about ownership, and deleting dynamically created objects. If you don't have dynamically created objects, you don't normally want smart pointers:
{
int i = 42;
auto_ptr <int> p( & i ); // bad!
}
You really don't want to do this, as when the autopointer goes out of scope, it will attempt to delete i. Unfortunately, i was not created dynamically, so bad things will happen. So you need both kinds of pointer, smart and normal, in most C++ programs.
The auto_ptr has an ownership model for the object it points at. You cannot have multiple refrences to the same object, and you cannot put them in stl containers and such - code that looks like it does that is actually transferring ownership, and going to cause nasty difficult-to-track-down bugs in production.
boost's shared_ptr is in almost all cases much more practical.
The main drawback of std::auto_ptr
is that it has the transfer-of-ownership semantic. That makes it impossible to store std::auto_ptr
in STL containers because the containers use the copy constructor when you store or get an element.
Also, another important aspect that i have noticed about the std::auto_ptr
is that they cannot serve in the use of PIMPL idiom. This is because, they require the complete definition of the wrapped class's destructor. See this thread on c.l.c++.m for more detailed discussion.
Update: Transfer of ownership
class Test {};
std::auto_ptr<Test> ap_test_1(new Test);
std::auto_ptr<Test> ap_test_2(new Test);
ap_test_2 = ap_test_1; // here ap_test_1's ownership is transferred i.e. ap_test_2 is the
// new owner and ap_test_1 is NULL.
See this thread on Herb Sutter's site for more details on what this means when used in a STL container used by STL algorithms.
Don't confuse auto pointers (std::auto_ptr) with the family of smart pointers (notably std::auto_ptr, boost::scoped_ptr and boost::shared_ptr).
I pretty much never use auto pointers because, most of the time, i'd rather use references. The only time when i do is for member variables that can't be instantiated in the constructor of the object.
On the contrary, smart pointers are very powerful, but that's not your question, i guess :)
The advantages is that for simple use, they do their job.
void foo() {
std::auto_ptr<int> bar(new int);
// do the stuff that potentially throw
} // the auto_ptr destructor will call delete here
The disadvantage is that as soon as you escape from this simple use, you hit the bad semantics of auto_ptr.
std::auto_ptr<int> foo(new int);
std::auto_ptr<int> bar = foo; // foo is changed here! It does not have ownership anymore.
You'd better use unique_ptr and shared_ptr that have good semantics, and that are available in boost::, and will be available in std:: in the next C++ standard
The short story: std::auto_ptr can't be shared, regular pointers can.
And then there's Boost.SmartPointer
Maybe the biggest reason on why it's not widely used:
The std::auto_ptr has a tremendous disadvantage: It can not be copied without destruction. When you need to make a copy of an auto pointer, the original instance is destroyed. This means you may only have a single copy of the object at any time. This also means that auto_ptr can not be used with standard containers, such as vector, deque, list, set, and map. In fact, it can hardly be used in any class that relies on copy construction.
Furthermore, auto_ptr is not safe, because nothing prevents you from doing a copy accidentally. And if you do so, you destroy the original copy. Also, some less standard compliant C++ compilers let you store forward declared objects in an auto_ptr, and use that without ever including the full definition of the class. This always results in a memory leak.
The main raison d'être for auto_ptr is to transfer ownership in an exception safe manner. Although most people use it as a poor man's boost::scoped_ptr.
The primary usage is for functions returning using objects pointers as parameters or return values.
For example a factory function
std::auto_ptr<MyClass> createMyClass(MyClass::Type type) {
if (type == MyClass::TypeOne) {
return std::auto_ptr(new MyClassOne);
}
else {
return std::auto_ptr(new MyClassTwo);
}
}
void foo() {
std::auto_ptr<MyClass> myc = createMyClass(MyClass::TypeOne);
// use myc
}
While this code is very simple and no exceptions should be thrown if exceptions are thrown myc handles it correctly, where doing this with raw pointers would be hard.
boost::shared_ptr can be used also, but this provides more functionality than required it also indicates that you expect the object to be shared. Where with auto_ptr is simpler and you're are clearly stating that you are transferring ownership.
I was recently told about boost::unique_ptr which seem to have the same usage as auto_ptr without the drawbacks.
see http://stackoverflow.com/questions/974964/best-practice-when-returning-smart-pointers/ for more info