簡體   English   中英

在刪除動態分配對象的指針向量中的元素之前,我需要做什么?

[英]What do I need to do before deleting elements in a vector of pointers to dynamically allocated objects?

我有一個向量,我填充指向對象的指針。 我正在努力學習良好的記憶管理,並提出一些一般性問題:

  1. 當我完成向量時,我必須遍歷它並在每個指針上調用delete嗎?
  2. 為什么我不必在沒有新語句的情況下調用向量或我聲明的任何其他變量上的delete,但必須在指針上調用delete?
  3. 如果在返回的函數中聲明向量(導致向量超出范圍),C ++是否會為我釋放指針的內存?
  1. 使用模板內存分配器實現向量,這些分配器為您處理內存管理,因此它們有點特殊。 但作為一般經驗法則,您不必對未使用new關鍵字聲明的變量調用delete ,因為堆棧和堆分配之間存在差異。 如果在堆上分配了東西,則必須刪除它(釋放)以防止內存泄漏。
  2. 不。在迭代所有元素時,您必須顯式調用delete myVec[index]

例如:

for(int i = 0; i < myVec.size(); ++i)
   delete myVec[i];

話雖如此,如果您計划在向量中存儲指針,我強烈建議使用boost::ptr_vector自動處理刪除。

當我完成向量時,我必須遍歷它並在每個指針上調用delete嗎?

好吧,你不必手動循環,你也可以使用算法:

#include <vector>
#include <algorithm>
#include <memory>

int main()
{
    std::vector<Base*> vec;
    vec.push_back(new Derived());
    vec.push_back(new Derived());
    vec.push_back(new Derived());

    // ...

    std::for_each(vec.begin(), vec.end(), std::default_delete<Base>());
}

如果您沒有C ++ 0x編譯器,可以使用boost:

#include <boost/lambda/lambda.hpp>
#include <boost/lambda/construct.hpp>

std::for_each(vec.begin(), vec.end(), boost::lambda::delete_ptr());

或者你可以編寫自己的仿函數:

struct delete_ptr
{
    template <class T>
    void operator()(T* p)
    {
        delete p;
    }
};

std::for_each(vec.begin(), vec.end(), delete_ptr());

如果您有權訪問C ++ 0x,也可以使用std :: unique_ptr。 它取代了不能在容器中使用的已棄用的std :: auto_ptr。

你用new分配的所有內容都必須在以后delete 您沒有使用new顯式分配的對象不應該delete

如果您不想手動管理對象但希望向量“擁有”它們,那么最好按值存儲對象而不是存儲指針。 因此,您可以使用std::vector<SomeClass>而不是std::vector<SomeClass*> std::vector<SomeClass>

作為David Titarenco提到的boost::ptr_vector的替代方法,您可以輕松修改std :: vector以自動釋放內存以包含刪除指針:

template<class T>
class Group : public std::vector<T>
{
public:
    virtual ~Group() {};
};

template<class T>
class Group<T *> : public std::vector<T *>
{
public:
    virtual ~Group()
    {
        std::vector<T *>::reverse_iterator it;
        for (it = this->rbegin(); it != this->rend(); ++it)
            delete *it;
    }
};

std :: vector提供的所有功能都是繼承的,因此您可以使用相同的方式添加項目:

Group<Foo *> *bar = new Group<Foo *>();
bar->push_back(new Foo());
bar->push_back(new DerivedFoo());

// Deleting the Group will free all memory allocated by contained pointers
delete bar;

暫無
暫無

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

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