Удалите все элементы из С++ std::vector
Я пытаюсь удалить все из std::vector
с помощью следующего кода
vector.erase( vector.begin(), vector.end() );
но это не сработает.
Обновление: не очищает ли элементы, удерживаемые вектором? Я не хочу этого, поскольку я все еще использую объекты, я просто хочу очистить контейнер
Ответы
Ответ 1
Я думаю, вы должны использовать std::vector::clear
:
vec.clear();
EDIT:
Не очищает деструкцию элементов удерживаемый вектором?
Да, да. Он вызывает деструктор каждого элемента в векторе перед возвратом памяти. Это зависит от того, какие "элементы" вы храните в векторе. В следующем примере я храню объекты в себе внутри вектора:
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).
Если вы хотите совместно использовать объекты между различными контейнерами, вы можете сохранить в них указатели. В этом случае, когда вызывается clear
, освобождается только память указателей, фактические объекты не затрагиваются:
std::vector<myclass*> myvector;
...
myvector.clear(); // calling clear will do:
// 1) ---------------
// 2) size == 0 (the vector contained "pointers" not the actual objects).
В вопросе в комментарии я думаю, что getVector()
определяется следующим образом:
std::vector<myclass> getVector();
Возможно, вы хотите вернуть ссылку:
// vector.getVector().clear() clears m_vector in this case
std::vector<myclass>& getVector();
Ответ 2
vector.clear()
должен работать на вас. Если вы хотите уменьшить емкость vector
вместе с прозрачным, тогда
std::vector<T>(v).swap(v);
Ответ 3
vector.clear() фактически совпадает с vector.erase(vector.begin(), vector.end()).
Если ваша проблема связана с вызовом delete
для каждого указателя, содержащегося в вашем векторе, попробуйте следующее:
#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 );
Стандартный отказ от ответственности: код, написанный в браузере, непроверенный.
Ответ 4
Используйте v.clear() для удаления вектора.
Если ваш вектор содержит указатели, очищает вызовы деструктора для объекта, но не удаляет память, на которую ссылается указатель.
vector<SomeClass*> v(0);
v.push_back( new SomeClass("one") );
v.clear(); //Memory leak where "one" instance of SomeClass is lost
Ответ 5
Не работает v.clear()
по какой-то причине?
Ответ 6
Если вы сохраняете указатели в контейнере и не хотите беспокоиться об их ручном уничтожении, используйте boost shared_ptr. Вот пример для std::vector, но вы можете использовать его для любого другого контейнера STL (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;
}
Ответ 7
Добавление к вышеупомянутым преимуществам swap().
Что clear()
не гарантирует освобождение памяти. Вы можете использовать swap()
следующим образом:
std::vector<T>().swap(myvector);
Ответ 8
Если ваш вектор выглядит так: std::vector<MyClass*> vecType_pt
, вам нужно явно освободить память. Или если ваш вектор выглядит следующим образом: std::vector<MyClass> vecType_obj
, конструктор будет вызываться vector.Please выполните приведенный ниже пример и поймите разницу:
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;
}