0

テンプレートの削除に問題があります。
私のテンプレートとデストラクタ:

template<class S, class T>  
class Consortium
{

private :

    map<const S, Node<T>*> m_consortiumMap;
    Heap<T>m_consortiumHeap;

public :

    ~Consortium();
    void Insert(const S key, T toAdd);
    void Update(const S key);
    void Remove(const S key);
    const T Top();
};

template<class S, class T>
Consortium<S,T>::~Consortium()
{
    m_consortiumMap.clear();
    delete &m_consortiumHeap.;
}

私のヒープとデストラクタ:

template <class T>
class Heap
{
private :

    vector<Node<T>*> m_heapVector;

public :

    ~Heap();

    int parent(int i) const {return i / 2;}
    int left(int i) const {return 2 * i;}
    int right(int i) const {return 2 * i + 1;}
    void heapify(int index);
    Node<T>* extractMin ();
    void heapDecreaseKey (int index, Node<T>* key);
    void MinHeapInsert (Node<T>* key);
    Node<T>* ExtractNode(int index);
    Node<T>* top ()const {return m_heapVector[0];}

};  

template<class T>
Heap<T>::~Heap()
{
    for (int i = 0 ; i < m_heapVector.size() ; i++)
        m_heapVector.erase(m_heapVector.begin() + i);
}

これはテンプレートを保持するオブジェクトです。これにも問題があります。

class Garage
{
    private :

        Consortium<string, Vehicle*> m_consortium;

    public :

        ~Garage() {delete &m_consortium;}
};

ここで何が問題なのですか?

4

4 に答える 4

2

これは一見間違っています:

delete &m_consortiumHeap;

deleteで割り当てたものだけを指定する必要がありますnewm_consortiumHeapはクラスの一部であり、クラスが割り当てられると自動的に割り当てられ、クラスが割り当て解除されると自動的に割り当て解除されます。明示的にすることはできませんし、してはいけませんdelete

これには逆の問題がある可能性があります。

m_consortiumMap.clear();

内容 m_consortiumMapはポインタです。表示したコードからはわかりませんが、マップ内のノードがConsortiumを使用してクラスによって割り当てられている場合はnew、それらをdelete編集する必要があります。そうしないと、メモリリークが発生します。マップをクリアすると、ポインタが削除されるだけで、ポインタが指すメモリの割り当てが解除されません。delete最初に、マップと各要素を反復処理する必要があります。要素の割り当てを解除することは重要ですが、マップ自体はとにかく直後に破棄されるため、デストラクタでマップをクリアすることは無意味です。

これはただ困惑しています:

for (int i = 0 ; i < m_heapVector.size() ; i++)
    m_heapVector.erase(m_heapVector.begin() + i);

まず、私が言ったことはすべて以下にm_consortiumMapも当てはまりますm_heapVector。コンテンツがクラスによって割り当てられた場合はnew、デストラクタでそれらを割り当てるHeap必要があります。deleteまた、上記のループに論理エラーがあることは言うまでもなく、ベクトルからポインターを消去することは無意味です。コンテナを反復処理するときは、イテレータ自体を使用する必要があります。

for (std::vector<Node<T>*>::iterator i = m_heapVector.begin() ; i != m_heapVector.end() ; i++)

また、std::vectorのようstd::mapに、のように関数がありclear()ますが、私が言ったように、デストラクタでベクトルをクリアすることは無意味です。本当にやりたいのは、要素の割り当てを解除することです(必要な場合)。

于 2010-09-23T13:37:06.530 に答える
2

newオブジェクトの作成に使用しなかった場合、それを削除するために使用deleteすることはできません。

于 2010-09-23T13:37:17.883 に答える
1

ベクトル内の要素が指すオブジェクトを削除したい場合があります。Erase メソッドはそれを行いません。ポイントされたオブジェクトを破棄せずに、ベクターからポインター要素を削除するだけです。したがって、メモリリークを避けるために、最初にポイントされたオブジェクトを削除する必要があります(私は推測します)。あなたはこれを冷静にします:

for( vector<Node<T>*>::iterator iter = m_heapVector.begin(), endI = m_heapVector.end(); iter != endI; ++iter)
{
   delete *iter;
}

// m_heapVector.clean(); // Not necessary in destructor, since the vector will be destroyed anyway.

C++0x 関数の使用:

std::for_each( m_heapVector.begin(), m_heapVector.end(), []( Node<T>* node) { delete node; });

また、clear()コンテナーのメソッド (この場合はベクター) を使用して、すべての要素を削除します。

于 2010-09-23T13:31:48.117 に答える
0

m_consortiumHeap はクラスのデータ メンバーであるため (それへのポインターではなく、直接)、明示的に削除する必要はありません。Consortium インスタンスが破棄されると、m_consortiumHeap のデストラクタが自動的に呼び出されます。

于 2010-09-23T13:32:07.303 に答える