Delete all items from a c++ std::vector

C++StlVector

C++ Problem Overview


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

C++ Solutions


Solution 1 - C++

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(); 

Solution 2 - C++

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);

Solution 3 - C++

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.

Solution 4 - C++

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

Solution 5 - C++

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

Solution 6 - C++

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;
}

Solution 7 - C++

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);

Solution 8 - C++

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;
    }

Solution 9 - C++

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();

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
QuestionmichaelView Question on Stackoverflow
Solution 1 - C++Khaled AlshayaView Answer on Stackoverflow
Solution 2 - C++aJ.View Answer on Stackoverflow
Solution 3 - C++DevSolarView Answer on Stackoverflow
Solution 4 - C++Alex BView Answer on Stackoverflow
Solution 5 - C++RobView Answer on Stackoverflow
Solution 6 - C++Dominic.wigView Answer on Stackoverflow
Solution 7 - C++SamerView Answer on Stackoverflow
Solution 8 - C++SatbirView Answer on Stackoverflow
Solution 9 - C++SinipeltoView Answer on Stackoverflow