Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

stl

vector

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.

like image 821
cesar Avatar asked Jun 15 '11 04:06

cesar


People also ask

What does vector erase do?

vector::eraseErases the specified elements from the container. 1) Removes the element at pos . 2) Removes the elements in the range [first, last) . Invalidates iterators and references at or after the point of the erase, including the end() iterator.

Does a vector delete itself?

No. The std::vector will automatically de-allocate the memory it uses.

Do you need to delete a vector of pointers?

Yes, the code has a memory leak unless you delete the pointers. If the foo class owns the pointers, it is its responsibility to delete them. You should do this before clearing the vector, otherwise you lose the handle to the memory you need to de-allocate.

Does vector erase return value?

@Drt The iterator returned will point to element immediately after the element(s) that were erased. If there is no such element (erased the last element in the vector) then it returns end() .


1 Answers

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; } 
like image 51
Alok Save Avatar answered Oct 02 '22 19:10

Alok Save