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