2010-11-11 50 views
0

的我有一個表指針在A型(稱爲利斯塔)容器的指針的B.一個矢量(每一個目的是具有專用屬性的容器類:std<vector> *B)。然後,我宣佈一個指針(被稱爲具有相同類型爲C),做一個for循環通過利斯塔讓所有指針B和把他們在C.當我放棄我的計劃,我又解除分配解除分配利斯塔第一,利斯塔他們自己的指針向量B.然後我釋放指針C,但程序崩潰。解除分配指針

我有這個調試了一下,知道的釋放點什麼的時候,指針C,所以它不知道要解除什麼。

難道我做錯了嗎?或者我的問題有什麼解決方案?

對不起,我把下面

//Class A 
#pragma once 

#include "MyContainer.h" 
class B; 
class A 
{ 
public: 
    A(); 
    ~A(); 
    MyContainer<B> *pListOfB; 
} 

A::A() 
{ 
    pListOfB = new MyContainer<B>; 
} 
A::~A() 
{ 
    if(pListOfB) 
    { 
     delete pListOfB; 
     pListOfB = NULL; 
    } 
} 
//Class C 
#pragma once 

#include "MyContainer.h" 
class B; 
class C 
{ 
public: 
    C(); 
    ~C(); 
    MyContainer<B> *pListOfB; 
    void getListOfB(MyContainer<A> *pListOfA); 
} 

C::C() 
{ 
    pListOfB = new MyContainer<B>; 
} 
C::~C() 
{ 
    if(pListOfB) 
    { 
     delete pListOfB; 
     pListOfB = NULL; 
    } 
} 
void C::getListOfB(MyContainer<A> *pListOfA) 
{ 
    for(pListOfA->isBegin(); !pListOfA->isEnd();) 
    { 
     A *pA = pListOfA->getNext(); 
     for(pA->isBegin(); !pA->isEnd();) 
     { 
      B* pB = pA->*pListOfB->getNext(); 
      pListOfB->add(pB); 
     } 
    } 
} 
//Class MyContainer 
#pragma once 

#include <vector> 

template <class T> 
class MyContainer 
{ 
public: 
    MyContainer(void); 
    ~MyContainer(void); 
    T* getNext(); 
    void removeAll(); 
    void add(T* t); 
    void isBegin(); 
    bool isEnd(); 
private: 
    std::vector<T*> items; 
    typename std::vector<T*>::iterator it; 
}; 

template <class T> MyContainer<T>::~MyContainer() 
{ 
    removeAll(); 
} 

template <class T> void MyContainer<T>::add(T *t) 
{ 
    items.push_back(t); 
} 

template <class T> void MyContainer<T>::removeAll() 
{ 
    while(!isEmpty()) 
    { 
     std::vector<T*>::iterator tempIt =items.begin(); 
     T* t = (*tempIt); 
     items.erase(tempIt); 
     delete t; 
     t=NULL; 
    } 
} 

template <class T> 
T* MyContainer<T>::getNext() 
{ 
    if(isEnd() || isEmpty()) 
     return NULL;  
    return (T*)(*(it++)); 
} 

template <class T> 
void MyContainer<T>::isBegin() 
{ 
    it = items.begin(); 
} 

template <class T> 
bool MyContainer<T>::isEnd() 
{ 
    return it==items.end(); 
} 

我的代碼我了以下行動: 1.初始列表的對象myContainer中* pListOfA; 2.將B數據到在pListOfA 3.初始C對象 4.調用C對象操作getListOfB每個A對象從pListOfA獲得B數據。 5.退出程序

程序首先釋放pListOfA,然後每個A釋放它們自己的pListOfB。在該程序之後,dealloc C對象依次dealloc pListOfB屬性C.但pListOfB指向無,因爲pListOfA將每個數據解除分配。所以我的程序崩潰了。 我通過rem修復了在C類的dtor中刪除pListOfB的行,但是我在該行發現了一條警告內存泄漏。 這就是我所有的問題。請給我看看正確的方法。提前致謝。

+1

是的,你做錯了什麼;否則你的程序不會崩潰。但是,從上面的描述中推斷出你做錯了什麼是非常困難的。我建議展示一個重現問題的最小程序。 – 2010-11-11 04:33:16

+1

'std * B'?你確定? – 2010-11-11 04:34:31

+1

是的,沒有代碼,像「A類型的列表指針」這樣的東西真的很混亂。 – ssube 2010-11-11 04:35:33

回答

0
  • 首先,你分配
  • 則「取放」的地方(不分配,只是複製三分球)
  • 然後取消分配
  • 然後取消分配。 ...等待
+0

換句話說,您將列表的內容複製到另一個列表,但實際上並沒有克隆這些對象。這些列表引用了相同的對象。所以,當你刪除第一個列表的對象時,你也刪除了第二個列表引用的對象。刪除第二個列表然後再刪除一個對象並崩潰。 – 2011-02-08 08:10:47

0

正確的方法是不使用普通指針

當你開始寫delete pointer;的時候,你必須重新考慮你是否真的需要這個指針,如果你確實需要它,如果沒有一些預先打包的智能指針類可以從內存管理的負擔您。

你貼可在不使用的指針的完全寫的示例代碼:

//Class A 
#pragma once 

#include "MyContainer.h" 
#include "B.h" 

class A 
{ 
public: 
    A() { }; 
    ~A() { }; 
    MyContainer<B> ListOfB; 
}; 

//Class C 
#pragma once 

#include "MyContainer.h" 
#include "B.h" 

class C 
{ 
public: 
    C() { }; 
    ~C() { }; 
    MyContainer<B> ListOfB; 
    void getListOfB(MyContainer<A>& ListOfA); 
}; 

void C::getListOfB(MyContainer<A>& ListOfA) 
{ 
    for(ListOfA.isBegin(); !ListOfA.isEnd();) 
    { 
     A& anA = ListOfA.getNext(); 
     for(anA.ListOfB.isBegin(); !anA.ListOfB.isEnd();) 
     { 
      B aB = anA.ListOfB.getNext(); 
      ListOfB.add(aB); 
     } 
    } 
} 

//Class MyContainer 
#pragma once 

#include <vector> 

template <class T> 
class MyContainer 
{ 
public: 
    MyContainer(void); 
    ~MyContainer(void) { }; 
    T& getNext(); 
    void removeAll(); 
    void add(const T& t); 
    void isBegin(); 
    bool isEnd(); 
private: 
    std::vector<T> items; 
    typename std::vector<T>::iterator it; 
}; 

template <class T> void MyContainer<T>::add(const T& t) 
{ 
    items.push_back(t); 
} 

template <class T> void MyContainer<T>::removeAll() 
{ 
    items.clear(); 
} 

template <class T> 
T& MyContainer<T>::getNext() 
{ 
    if(isEnd() || isEmpty()) 
     return throw std::out_of_range(""); 
    return *it++; 
} 

template <class T> 
void MyContainer<T>::isBegin() 
{ 
    it = items.begin(); 
} 

template <class T> 
bool MyContainer<T>::isEnd() 
{ 
    return it==items.end(); 
} 

如果B實例需要被A類和C類之間共享(在A和C的列表既指相同的B對象),那麼你可以在列表中存儲shared pointers

+0

@downvoter:評論爲什麼downvote會很好。 – 2010-11-12 14:56:07

+0

感謝您的幫助,我會試一試 – ducva 2010-11-14 16:06:46

+0

我的想法背後是三類A B C,它是在A類和C類之間同步數據。它意味着當B類由A類或C類改變時,其他類將知道這種改變。所以我決定將A級和C級指向相同的數據。但經過幾天的測試和思考,我意識到我試圖做的事情會導致內存泄漏。我肯定必須在我的項目中使用指針來傳遞參數。所以我的即時思考是每個A或C類將存儲一個B類的副本,並且每次我改變一個類的數據時,我也必須改變其他類。你知道我的問題更好的方法嗎? – ducva 2010-11-15 12:43:19