2014-02-21 46 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();