Why can't I use auto_ptr in STL?

Submitted by date of submission user level 

Bulent Ozkir April 13, 2001 Beginner 

  

  

You can not use auto_ptr inside STL containers like vector. The reasons are 1) ownership problem 2) auto_ptr does not have suitable conversion function yet... The resolution is using a shared_pointer like www.boost.org

  shared_ptr. Or a useless sample as I provided in the end if using auto_ptr is a must...

 

// The following code sucks!!!

// but ANSI C++ compilers do not compile it, except for MSVC++

// because of the declaration

// auto_ptr(const auto_ptr<_Ty>& _Y) _THROW0()

//     : _Owns(_Y._Owns), _Ptr(_Y.release()) {}

 

 

    // Now the right way ??? NO , This code fragment sucks!!!

     vector > v;

     v.insert(v.begin(),

              auto_ptr(new string("Florence")));

     v.insert(v.begin(), auto_ptr(new string("Milan")));

     v.insert(v.begin(), auto_ptr(new string("Venice")));

     // Everything is fine since auto_ptrs transfer ownership of

     // their pointers when copied

     // Now remove the first element

     v.erase(v.begin());

     // Success

     // When auto_ptr(string("Venice")) is erased (and destroyed)

     // string("Venice") is deleted

 

 

My following code worked %100 , but it seemed unnecessary because of the footnote, storing pointers if they are not on the heap is really mesy and meaningless, I would rather prefer objects/references for the scope; ( I

used BCB++5 instead of VC++6 because of ANSI incompatiblities in this test...)

#include 

#include 

using namespace std;

class MyClass

{

public:

MyClass(){};

MyClass(int y):x(y){};

int x;

};

vector myVec;

        auto_ptr myPtr(new MyClass(5));

        myVec.push_back(myPtr.release());

        auto_ptr myPtr2(new MyClass(19));

        myVec.push_back(myPtr2.release());

        ShowMessage((myVec.at(0))->x);

        ShowMessage((myVec.at(1))->x);

     vector::const_iterator first = myVec.begin();

     vector::const_iterator last = myVec.end();

       while (first != last)

            delete *first++;

Pointers and STL

As you might've noticed, STL containers manage the storage for objects, not pointers, and this has caused some trepidation about using STL for projects which need to store pointers in various STL containers. I strongly suggest

people revisit their designs and not store pointers, but if you have no choice, here's what I have found so far regarding STL containers and pointers to defined types. Gotcha's with storing pointers to objects Contrary to what some believe, STL does not care if you're storing pointers to objects instead of objects in its containers. However, more often than

not, containers of pointers may be a design flaw that leads to memory leaks and such lovely things. There are a few obvious exceptions: 

Large objects that are too expensive to duplicate and are already constructed on the heap. Single object stored in multiple containers. This is quite common and I believe the right way to do is to wrap the pointers into a class the manages the objects, perhaps via a reference count. When you need to store objects derived from a (or a set of) base objects in a container. This is quite common in CAD systems where most manipulable objects are derived from a common base with a set of common semantics. See here for an example. Remember that C++ != Smalltalk, and true heterogeneous containers are simply too messy to do in C++.  

There are few notable gotcha's:

No pointers to local variables please. See the function change_phno for an example of this. Who manages the destruction? See here for an example of templatized sequence destructor. Most STL containers use < for comparison which may be meaningless in some contexts. This is where Smart pointers shine. Be careful when supplying a Comparator to STL containers need one, such as SET, MAP, etc. See here for a rather involved example. Also see here for another example. A better solution is to wrap the pointers in a simple class that you store in STL containers. For a trivial example, see here. Some compilers and STL implementations seem to have inordinate amount of

trouble when you store pointers to objects instead of objects, and it stems from construct and destroy functions in STL allocator design; eg., HP reference implementation comes with destroy specialized for pointers to all built-in types, so it works fine if you store int* in a container, but not when you store X*, where X is some user-defined data type.

 

--------------------------------------------------------------------------------

Bulent Ozkir is a Turkey based senior software engineer. He has worked as a senior support engineer for Microsoft from 1998 to 2000. In his over 5 years programming career he has been working on various programming technologies including VB, VC, Visual Interdev, JavaScript, ASP, HTML/DHTML, WMI, COM+, TCP/IP, IIS, SS3, MCIS25, ASP and SQL Server. His background includes B.A. Comp. Sc., MCSE + Internet and MCSD. See members area for more details.