繁体   English   中英

C ++向量动态内存释放/删除

[英]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

// ------------------------------------------------ -----

我有两个建议也是我的问题:

  1. 在这里使用智能指针来管理资源可以帮到你。

  2. 在堆栈上使用矢量对象会更好。

发生这种情况的原因非常简单,你可以通过擦除元素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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM