Does vector::erase() on a vector of object pointers destroy the object itself?

C++StlVector

C++ Problem Overview


I have a vector of pointers to objects. I need to remove an element from the vector and place that element in another list.

I read that erase can be used to remove the object from the vector, but I also read that it calls the objects destructor before doing so.

I need to know whether or not erasing the object will destroy it as well.

C++ Solutions


Solution 1 - C++

vector::erase
Removes from the vector container and calls its destructor but If the contained object is a pointer it doesnt take ownership of destroying it.

You will have to explicitly call delete on each contained pointer to delete the content it is pointing to, for example:

void clearVectorContents( std::vector <YourClass*> & a ) 
{    
    for ( int i = 0; i < a.size(); i++ ) 
    {       
        delete a[i];    
    }    
    a.clear(); 
} 

Storing raw pointers in standard containers is not a good idea. If you really need to store resources that have to be allocated by new, then you should use boost::shared_ptr. Check out the Boost documentation.

An more generic & elegant solution:
This solution makes use of for_each & templates as @Billy pointed out in comments:

// Functor for deleting pointers in vector.
template<class T> class DeleteVector
{
    public:
    // Overloaded () operator.
    // This will be called by for_each() function.
    bool operator()(T x) const
    {
        // Delete pointer.
        delete x;
        return true;
    }
};

And this can be called as:

for_each( myclassVector.begin(),myclassVector.end(),
          DeleteVector<myclass*>());

where, myclassVector is your vector containing pointers to myclass class objects.

Usage Example:

#include "functional"
#include "vector"
#include "algorithm"
#include "iostream"

//Your class
class myclass
{
    public:
        int i;
        myclass():i(10){}
};


// Functor for deleting pointers in vector.
template<class T> class DeleteVector
{
    public:
    // Overloaded () operator.
    // This will be called by for_each() function.
    bool operator()(T x) const
    {
        // Delete pointer.
        delete x;
        return true;
    }
};


int main()
{
    // Add 10 objects to the vector.
    std::vector<myclass*> myclassVector;
    
    for( int Index = 0; Index < 10; ++Index )
    {
        myclassVector.push_back( new myclass);
    }
   
    for (int i=0; i<myclassVector.size(); i++) 
    {
        std::cout << " " << (myclassVector[i])->i;
    }

    // Now delete the vector contents in a single  line.
    for_each( myclassVector.begin(),
              myclassVector.end(),
              DeleteVector<myclass*>());
 
    //Clear the vector 
    myclassVector.clear();
    
    std::cout<<"\n"<<myclassVector.size();

    return 0;
}

Solution 2 - C++

  • If you have a vector<MyObject> then MyObject::~MyObject will be called.
  • If you have a vector<MyObject*> then delete <MyObject instance> will not be called.

To move MyObject between two vectors, you need to first insert it into the destination vector, then erase the original. Note that this will create a new copy of the object. When moving pointers, you can just keep the pointer in a temporary variable, erase it from the vector, then insert wherever you need.

And here's another simple way to delete and then remove all the items in a vector:

template<class T> void purge( std::vector<T> & v ) {
    for ( auto item : v ) delete item;
    v.clear();
}

Solution 3 - C++

Yes, erase destroys the element. However, if you're placing the element in another container you probably made a copy putting it into that other container. The only way you'd run into issues is if you copied a pointer or something like that into the other container.

Solution 4 - C++

Yes, of course it will. If the object doesn't exist in the vector, where else would it exist?

Edit: This will not delete anything pointed to by a pointer. You should use automatic life-time managing pointers such as shared_ptr to manage object lifetimes.

Solution 5 - C++

Yes. vector::erase destroys the removed object, which involves calling its destructor.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioncesarView Question on Stackoverflow
Solution 1 - C++Alok SaveView Answer on Stackoverflow
Solution 2 - C++Tomas AndrleView Answer on Stackoverflow
Solution 3 - C++Billy ONealView Answer on Stackoverflow
Solution 4 - C++PuppyView Answer on Stackoverflow
Solution 5 - C++Dominic GurtoView Answer on Stackoverflow