[英]C++ vector dynamic memory deallocation/delete
当我尝试删除动态对象向量的动态内存元素时,我必须多次遍历向量的整个大小以确保完全释放。
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循环来确保完全释放。
我似乎错过了关于向量的内部工作的一些东西,我已经尝试阅读向量c ++参考,我理解向量将元素存储在一个连续的位置,并且他们为可能的增长分配额外的存储空间,但我无法理解这种行为这段代码。
您可以编写一个泛型函数来处理向量元素的释放和擦除
template<typename T>
void destroy_vector(std::vector<T*> &v)
{
while(!v.empty()) {
delete v.back();
v.pop_back();
}
}
一些评论
empty
的空容器 vector<T*>*
在智能指针中以避免内存泄漏 从向量中删除元素时,之后的元素将移动一个位置。 擦除索引0中的元素时,索引1中的元素将移动到索引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
// ------------------------------------------------ -----
我有两个建议也是我的问题:
在这里使用智能指针来管理资源可以帮到你。
在堆栈上使用矢量对象会更好。
发生这种情况的原因非常简单,你可以通过擦除元素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> = 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();
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.