2014-02-21 97 views
4

当我尝试删除动态矢量对象的动态内存元素时,我不得不遍历整个矢量大小,以确保完全释放。C++矢量动态内存释放/删除

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++参考,并且我知道矢量将元素存储在一个连续的位置,并且他们为可能的增长分配额外的存储空间,但是我失败了了解此代码的行为。

+3

'汽车=新的向量;'这是一个坏主意,为什么不'矢量汽车;'?你拿着原始指针项目已经足够复杂了一切...... –

+0

你注意到有'std :: erase()'函数顺便说一句。 –

+0

@πάνταῥεῖ没有'std :: erase'功能。你的意思是'std :: vector :: erase'或'std :: remove'? –

回答

1

当你从矢量中删除一个元素时,之后的元素被移动一个地方。当您擦除索引0中的元素时,索引1中的元素将移至索引0,并且在下一次迭代中不会被擦除。

从循环中进行擦除。无论如何,元素将在矢量析构函数中被删除。

+1

好吧,我知道当一个特定元素被删除或删除时元素必须移位。我想我可以释放所有元素,然后调用vector :: clear一次,使矢量大小为0并为空。 –

+0

@WadeG您可以使用clear清空矢量,但如果在此之后删除矢量,则它是多余的。 – user2079303

2

你可以写一个通用的函数来处理向量的元素都释放和擦除

template<typename T> 
void destroy_vector(std::vector<T*> &v) 
{ 
    while(!v.empty()) { 
     delete v.back(); 
     v.pop_back(); 
    } 
} 

一些言论

  • 在与empty务必检查集装箱空箱
  • 商店中的vector<T*>*智能指针以避免内存泄漏
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. 在堆栈上使用矢量对象会更好。

0

这种情况发生的原因非常简单,您可以通过擦除元素i,然后递增i,从地毯下拉出地毯......

I = 0:汽车= {0} [1] [2] [3]

擦除(开始+ I)

I = 0:汽车= {1} [2] [3]

我+ +

I = 1:汽车= [1] {2} [3]

擦除(开始+ I)

I = 1:汽车= [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();