当我尝试删除动态对象向量的动态内存元素时,我必须多次迭代向量的整个大小以确保完全释放。
class CV{
public:
float x;
float y;
CV();
CV(float, float);
~CV();
};
int main(){
vector<CV*>* cars;
cars = new vector<CV*>;
//create objects with new, push into vetor
for(int j=0;j<4;j++){
cars->push_back( new CV(10.0+j, 11.99+j) );
}
while( cars->size() > 0 ){
for(int i=0;i<cars->size();i++){
delete (*cars)[i];
cars->erase( cars->begin()+i);
}
cout << "size:"<< cars->size() << endl;
}
delete cars;
return 0;
}
这将输出:
size:2
size:1
size:0
当我尝试删除时,向量似乎迭代每个第二个元素,因为我需要额外的while循环来确保完全释放。
我似乎错过了关于vector的内部工作的一些东西,我已经尝试过阅读vector c ++参考,我理解向量将元素存储在一个连续的位置,并且他们为可能的增长分配额外的存储空间,但是我没有了解此代码的行为。
答案 0 :(得分:3)
您可以编写一个通用函数来处理向量元素的重新分配和擦除
template<typename T>
void destroy_vector(std::vector<T*> &v)
{
while(!v.empty()) {
delete v.back();
v.pop_back();
}
}
一些评论
empty
查看空容器vector<T*>*
存储在智能指针中以避免内存泄漏答案 1 :(得分:1)
当您从矢量中删除元素时,之后的元素会移动一个位置。擦除索引0中的元素时,索引1中的元素将移动到索引0,并且在下一次迭代中不会被擦除。
从循环中删除。无论如何,元素将在向量析构函数中被删除。
答案 2 :(得分:0)
我认为这里真正的问题是你错过了for循环条件检查。 我对您的代码做了一些小改动:
auto validateLoopCondition = [](int index, const vector<CV*> *vecpCV)
{
cout << "validate loop condition: i = " << index << ", size:" << vecpCV->size()
<< (index < vecpCV->size() ? ", keep it" : ", break out\r\n---------------\r\n")
<< endl;
};
for (int i = 0; validateLoopCondition(i, cars) , i < cars->size(); i++)
{
delete (*cars)[i];
cars->erase(cars->begin() + i);
}
cout << "size:" << cars->size() << endl;
//-out put-----------------------------------------------
validate loop condition: i = 0, size:4, keep it
validate loop condition: i = 1, size:3, keep it
validate loop condition: i = 2, size:2, break out
---------------
size:2
validate loop condition: i = 0, size:2, keep it
validate loop condition: i = 1, size:1, break out
---------------
size:1
validate loop condition: i = 0, size:1, keep it
validate loop condition: i = 1, size:0, break out
---------------
size:0
// --------------------------------------------- --------
我有两条建议也是我的问题:
在这里使用智能指针管理资源可以帮到你。
在堆栈上使用矢量对象会更好。
答案 3 :(得分:0)
发生这种情况的原因非常简单,你可以通过擦除元素i然后递增i来从自己的脚下拉出地毯......
i = 0:cars = {0} [1] [2] [3]
擦除(开始+ i)
i = 0:cars = {1} [2] [3]
我+ +
i = 1:cars = [1] {2} [3]
擦除(开始+ i)
i = 1:cars = [1] {3}
我+ +
i&gt; = cars.size()
使用像这样的擦除是低效的。您可以考虑以下两种方法:
while (!cars.empty()) {
delete cars.back();
cars.pop_back();
}
或效率更高
for (size_t i = 0; i < cars.size(); ++i) {
delete cars[i];
}
cars.clear();