2010-06-24 65 views
1

我有2個類,說A & B.類B有它自己的析構函數。在A級,我有一個指針的向量B類的物體的向量如下:刪除用戶定義的向量 - C++

vector<B*> vect; 

在析構函數爲A級,我該如何找回記憶?如果我循環遍歷向量,是否檢索每個對象並在每個檢索的對象上使用delete?我在析構函數中試過了,但它是段錯誤。

任何幫助解決這個問題是非常受歡迎的。我很抱歉,但我無法發佈代碼。

+1

在我們回答這個問題之前。我們必須知道你如何將東西放入向量中(是否用new創建的對象(這會打開另一個擁有剛剛創建的對象的問題))。另一個問題是你爲什麼要把指針放在向量中。該向量被設計爲擁有'對象'的所有權,所以除非你的B是多態的,否則將B對象(不是指針)放入向量中可能會更好。 – 2010-06-24 21:25:55

回答

1

其他一些帖子指出,你最好使用智能指針而不是指針。如果您因爲任何原因必須使用指針,您應該首先在循環中刪除它們。

for (std::vector<B*>::iterator it = vect.begin(); it != vect.end(); ++it) 
    delete (*it); 
vect.clear(); 

編輯: 如果在析構函數程序段錯誤那麼你的代碼是錯誤的。也許你在向量中放置了堆棧元素,但是要刪除它必須放在堆上的對象。

#include <iostream> 
#include <vector> 
#include <string> 

class data { 
public: 
    std::string d; 
    data(std::string _d) : d(_d) { } 
}; 

class container { 
public: 
    std::vector<data*> c; 
    container() { c.clear(); } 
    void add (data *d) { c.push_back(d); } 
    ~container() { 
     for (std::vector<data*>::iterator it = c.begin(); it != c.end(); ++it) 
      delete (*it); 
     c.clear(); 
    } 
}; 

int main (int argc, char* argv[]) { 

    typedef std::vector<std::string> sVec; 
    typedef sVec::iterator sVecIter; 

    std::vector<std::string> cmd (argv+1, argv+argc); 

    { 
    container k;    
    for (sVecIter it = cmd.begin(); it != cmd.end(); ++it) 
     k.add(new data((*it))); 

    } 

    return 0; 

} 

這工作沒有問題。

1

是的,如果B*類型的項目指向堆中分配的對象,那麼對於每個項目,您應該調用delete對象。

0

是的,你會循環矢量並刪除每個項目。問題在於你忘記了第42行上的毛巾操作員。

+0

呵呵,'問題是你忘了42號線上的毛巾操作員。' – 2010-06-24 20:42:50

+0

這是什麼「你忘了42號線上的毛巾操作員」這一切?開玩笑吧? – robinjam 2010-06-24 20:45:25

+0

是的,這是一個笑話。 – 2010-06-24 20:46:13

-1

從您的描述中可以看出,您的A類vect成員應該擁有B *指向的數據的一生所有權。

我會建議只是改變該項聲明

vector< std::tr1::shared_ptr<B> > vect; 

編輯:替換auto_ptr的用的std :: TR1的:: shared_ptr的

+2

'vector' plus'auto_ptr'是一個壞主意:http://www.gotw.ca/publications/using_auto_ptr_effectively.htm – 2010-06-24 20:42:47

+0

'auto_ptr'由於其奇怪的複製行爲,不適用於標準容器。 – 2010-06-24 20:45:59

+0

'std :: tr1 :: shared_ptr'會更好。 – robinjam 2010-06-24 20:46:56

4

如果A擁有的東西指向vect,那麼它應該能夠至deletevect內的每件商品。如果在這樣做時發生段錯誤,那麼您的代碼中存在一處錯誤。

一般來說,你最好使用智能指針。 Boost的ptr_vector(的Boost.Pointer Container一部分是專爲您的具體的例子,但一個簡單的std::vector<std::tr1::shared_ptr<B> >也將工作(儘管有更多的開銷和更尷尬的語法)。

0

你要避免存放在容器中的指針,當你需要管理壽命。

如果這是一個真正的主人,並保證是最後的清理,然後我會用

std::vector<B> vect; 

去。如果你有不同的引用和壽命可能重疊然後shared_ptr的效果會更好( std :: tr1或boost取決於編譯呃)

std::vector< boost::shared_ptr<B> > vect;