65
votes

I'm trying to delete everything from a std::vector by using the following code

vector.erase( vector.begin(), vector.end() );

but it doesn't work.


Update: Doesn't clear destruct the elements held by the vector? I don't want that, as I'm still using the objects, I just want to empty the container

9
clear() is there. U can use itvpram86
The update doesn't clarify things. What, exactly, are the vector elements? Are they pointers or objects? If they are objects, how are they still in use? Why do you want to empty the vector?David Thornley
1. What doesn't work? 2. Can it be that you don't know the difference between pointers and pointees? If you store pointers in a vector and then call clear() it will destroy the pointers, not the pointees!sellibitze
Your edit seems a bit confused. The vector owns the objects stored in it. If you remove the objects from the vector, then the copies are destroyed. That is unavoidable, they have nowhere to live. They're being removed from the place where they were stored. If you don't want that, then you can't meaningfully "empty the container".jalf
See this similar question: stackoverflow.com/questions/1514311/…John Carter

9 Answers

112
votes

I think you should use std::vector::clear:

vec.clear();

EDIT:

Doesn't clear destruct the elements held by the vector?

Yes it does. It calls the destructor of every element in the vector before returning the memory. That depends on what "elements" you are storing in the vector. In the following example, I am storing the objects them selves inside the vector:

class myclass
{
public:
    ~myclass()
    {

    }
...
};

std::vector<myclass> myvector;
...
myvector.clear(); // calling clear will do the following:
// 1) invoke the deconstrutor for every myclass
// 2) size == 0 (the vector contained the actual objects).

If you want to share objects between different containers for example, you could store pointers to them. In this case, when clear is called, only pointers memory is released, the actual objects are not touched:

std::vector<myclass*> myvector;
...
myvector.clear(); // calling clear will do:
// 1) ---------------
// 2) size == 0 (the vector contained "pointers" not the actual objects).

For the question in the comment, I think getVector() is defined like this:

std::vector<myclass> getVector();

Maybe you want to return a reference:

// vector.getVector().clear() clears m_vector in this case
std::vector<myclass>& getVector(); 
33
votes

vector.clear() should work for you. In case you want to shrink the capacity of the vector along with clear then

std::vector<T>(v).swap(v);
10
votes

vector.clear() is effectively the same as vector.erase( vector.begin(), vector.end() ).

If your problem is about calling delete for each pointer contained in your vector, try this:

#include <algorithm>

template< typename T >
struct delete_pointer_element
{
    void operator()( T element ) const
    {
        delete element;
    }
};

// ...
std::for_each( vector.begin(), vector.end(), delete_pointer_element<int*>() );

Edit: Code rendered obsolete by C++11 range-for.

9
votes

Use v.clear() to empty the vector.

If your vector contains pointers, clear calls the destructor for the object but does not delete the memory referenced by the pointer.

vector<SomeClass*> v(0);

v.push_back( new SomeClass("one") );

v.clear();  //Memory leak where "one" instance of SomeClass is lost
4
votes

Is v.clear() not working for some reason?

3
votes

If you keep pointers in container and don't want to bother with manually destroying of them, then use boost shared_ptr. Here is sample for std::vector, but you can use it for any other STL container (set, map, queue, ...)

#include <iostream>
#include <vector>
#include <boost/shared_ptr.hpp>

struct foo
{
    foo( const int i_x ) : d_x( i_x )
    {
        std::cout << "foo::foo " << d_x << std::endl;
    }

    ~foo()
    {
        std::cout << "foo::~foo " << d_x << std::endl;
    }

    int d_x;
};

typedef boost::shared_ptr< foo > smart_foo_t;

int main()
{
    std::vector< smart_foo_t > foos;
    for ( int i = 0; i < 10; ++i )
    {
        smart_foo_t f( new foo( i ) );
        foos.push_back( f );
    }

    foos.clear();

    return 0;
}
2
votes

Adding to the above mentioned benefits of swap(). That clear() does not guarantee deallocation of memory. You can use swap() as follows:

std::vector<T>().swap(myvector);
-1
votes

If your vector look like this std::vector<MyClass*> vecType_pt you have to explicitly release memory ,Or if your vector look like : std::vector<MyClass> vecType_obj , constructor will be called by vector.Please execute example given below , and understand the difference :

  class MyClass
    {
    public:
        MyClass()
        {
            cout<<"MyClass"<<endl;
        }
        ~MyClass()
        {
            cout<<"~MyClass"<<endl;
        }
    };
    int main() 
    {
        typedef std::vector<MyClass*> vecType_ptr;
        typedef std::vector<MyClass> vecType_obj;
        vecType_ptr myVec_ptr;
        vecType_obj myVec_obj;
        MyClass obj;
        for(int i=0;i<5;i++)
        {
            MyClass *ptr=new MyClass();
            myVec_ptr.push_back(ptr);
            myVec_obj.push_back(obj);
        }
        cout<<"\n\n---------------------If pointer stored---------------------"<<endl;
        myVec_ptr.erase (myVec_ptr.begin(),myVec_ptr.end());
        cout<<"\n\n---------------------If object stored---------------------"<<endl;
        myVec_obj.erase (myVec_obj.begin(),myVec_obj.end());
        return 0;
    }
-1
votes
class Class;
std::vector<Class*> vec = some_data;

for (unsigned int i=vec.size(); i>0;) {
    --i;
    delete vec[i];
    vec.pop_back();
}
// Free memory, efficient for large sized vector
vec.shrink_to_fit();

Performance: theta(n)

If pure objects (not recommended for large data types, then just vec.clear();