display | more...
The C++ STL (Standard Template Library) implementation of a generic smart pointer. Utilizes the C++ feature of a class destructor to the automatically free dynamically allocated memory of the object to which it references.

  class Foo
  {
  public:
     Foo(int val) : bar(val) {}
     int GetBar() const {return bar;}
  protected:
     int bar;
  };

  void print3()
  {
    //construct fooPtr with pointer to new Foo object   
    std::auto_ptr fooPtr = new Foo(3);
    
    //access referenced object as if fooPtr were a regular pointer
    cout << "bar = " << fooPtr->GetBar() << endl;

    //Foo object referenced by fooPtr is automatically freed as fooPtr goes out of scope
  }

auto_ptr<T> is a template class defined by the C++ STL which enforces the "single stored pointer" approach to memory management. As such, it is a type of smart pointer, but one with very odd semantics. So odd, in fact, that (like delete[]) I tried to make a freakshow entry out of it but couldn't make it any worse than it is. yahweh's writeup above may lead you to believe you can use it in your current or next project. Most likely, you cannot. While perfectly logical and consistent, the semantics are completely different from everything else in the language. In fact, the closest relatives would probably be linear logics and similar concepts from the implementation of programming languages and logics for reasoning about Forth programs.

An auto_ptr<T> holds a pointer to a T, which will be deleted when the auto_ptr<T> is destroyed -- the auto_ptr<T>'s destructor deletes the T (unless it's a null pointer).

Of course, this is a very dangerous thing to do if more than one auto_ptr<T> points at the same object. The solution (in typical C++ fashion) is to allow only one auto_ptr<T> to point at the T. How can this be achieved? By overloading operator= and the copy constructor to zero the source auto_ptr<T>! (Of course, it also releases the object held by the destination, as part of the same "only one auto_ptr<T>" policy.)

So if we say (assuming a default constructor for Obj)
{
  auto_ptr<Obj> x = new Obj;
  x = new Obj;              // Previous Obj released
  {
    auto_ptr<Obj> y = x;   // Now x==0 (!)
    // Do something with y...
  }                         // y destroyed, second Obj released
}                           // Still x==0, so we don't free the Obj again.
then everything works out reasonably nicely.

Note the absurd semantics of the auto_ptr<T>: merely appearing on the RHS of an assignment, or being passed as a parameter to a function (though not being passed by reference!) is enough to hijack the contents of your auto_ptr<T>. While it does make it very hard to have a memory leak or double free, the "only one auto_ptr<T>" policy is extremely unintuitive. About the closest you can get is with the linear logic approach to memory management.

A const auto_ptr<T> is, of course, an absurdity. Not so, of course, a auto_ptr<const T>.

Since auto_ptr<T>s are not Assignable (in the sense of the STL concept of that name), you cannot have a Container (vector, list, queue, ...) of them. Since they always call delete (and not delete[]), you can only use them with single objects, not with arrays. And since they appear to delete or zero themselves spontaneously, they are extremely hard to use.

A good use of an auto_ptr<T>s is as a return value which the caller of the function is expected to free. Since it's returning an auto_ptr<T>, the function is explicitly indicating it cannot free this memory. And if the caller continues to use auto_ptr<T>, the object will be deleted safely. It's just that actually writing the code feels very odd.

Better smart pointers exist, notably in the Loki class library of Modern C++ Design, or in the Boost libraries. Too bad they aren't in the standard -- auto_ptr<T> is the only "smart" pointer that comes with ISO C++.

Log in or register to write something here or to contact authors.