簡體   English   中英

為什么我需要手動刪除vector中的指針?

[英]Why do I need to delete pointers from vector manually?

為什么我需要手動刪除向量中動態創建的項目? 當向量被刪除時,為什么它們不會被刪除或者它的析構函數被調用?

通常是這樣的,但為什么需要?

vector<int*> v;
for (vector<int*>::iterator it = v.begin(); it != v.end(); ++it) 
{ 
   delete *it; 
}

首先,將原始指針存儲在向量中。 這些指針只是指針。 他們可以指向任何地方 它們可以指向本地對象,這些對象無法通過刪除delete 即使它們指向動態創建的對象,也不一定意味着用戶希望它們與向量一起死亡。 矢量如何知道這一切?

這是對象所有權的問題。 擁有該對象的人有責任及時刪除。 普通原始指針不表示所有權。 這就是為什么vector無法對是否需要刪除對象做出任何假設。 如果要告訴向量它擁有動態對象,請使用相應的智能指針。

其次,請注意您的刪除技術在一般情況下不一定安全。 某些標准容器假定您存儲在其中的數據始終有效。 當您對每個向量元素執行delete ,向量中的數據將變為“無效”(指針變為不確定)。 這對矢量來說沒問題。 但是在“更聰明”的容器中做這樣的事情,例如std::mapstd::unordered_set ,會導致問題。 即使您之后立即銷毀容器本身,容器的銷毀算法也可能需要分析(比較,散列等)各個元素的值。 而你剛剛用你的周期殺死它們。

智能指針自然會解決這個問題。 但是,如果必須對存儲在標准容器中的原始指針使用手動delete ,則可以采用更好的步驟順序

  1. i處檢索元素的值並將其存儲在指針p
  2. 從容器中刪除i處的元素
  3. delete p

最后,您最終得到一個空容器並delete d數據。 同樣,您的方法將適用於簡單的序列,如std::vectorstd::list ,但不要使用有序或散列的序列。

因為當你完成時,語言無法知道你是否需要它們保持活力。 如果你插入一些指向堆棧對象或類似的東西怎么辦? 繁榮。

但是,這可以通過使用智能指針來解決,智能指針實現適當的自動銷毀策略。 unique_ptrshared_ptr是最常用和最有用的。

不會調用析構函數,因為指針不擁有它指向的對象。

在C ++ 11中, std::unique_ptr<T>確實擁有它指向的對象。 在這種情況下,釋放指針時會調用析構函數,這可能是您想要的行為。 (如果你沒有C ++ 11編譯器但是有一個合理的最新的C ++ 11之前的編譯器,那么unique_ptr仍然是TR1的一部分。)

vector的實現只是為了刪除它的內存。 指針沒有解構器。 在C ++中,沒有垃圾收集或邏輯可以看到它是指針並且遞歸刪除它。

如果您想參加下一次ISO會議並提出建議,請成為我的客人,但對我而言,我只是將其置於inline函數中:

template<class T>
public static inline void deleteVectorPointer(std::vector<T*> v)
{
    for (vector<T*>::iterator i = v.begin(); i != v.end(); i++)
    {
        delete *i;
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM