1

具体的には、この質問が以前にここで尋ねられたのを見たことがあります

一般的な二分木ノード デストラクタの問題二分探索ツリー デストラクタ など

しかし、これまでのところ、コンストラクターで Node ポインターを NULL に設定するという答えが得られました。Node と Tree のコンストラクタとデストラクタのコードは次のとおりです。

template <class Type>
class Node {
protected:
    Type data;
public:
    Node<Type>(Type data) { this->data = data; }
};

バイナリ ツリー ノードは、上記のノードから継承します (継承を使用せず、単純に BinaryTreeNode をデータと共に使用する方が簡単であることはわかっていますが、練習しているので、この方法を選択しました)

BinaryTreeNode クラス:

template <class Type>
class BinaryTreeNode: public Node<Type> {
protected:
BinaryTreeNode<Type> *left;
BinaryTreeNode<Type> *right;
BinaryTreeNode<Type> *parent;
public:
BinaryTreeNode<Type>(Type data) : Node<Type>(data) {
    this->left = NULL;
    this->right = NULL;
    this->parent = NULL;
}
~BinaryTreeNode<Type>() {
    delete left;
    delete right;
    delete parent;
}
};

ツリーの場合:

template <class Type, template <class> class NodeType = BinaryTreeNode>
class BinaryTree {
protected:
    int size;
    NodeType<Type> *root;
public:
    ~BinaryTree<Type, NodeType>() {
        delete root;
    }
    BinaryTree<Type, NodeType>() {
        this->size = 0;
        this->root = NULL;
    }
};

主に、次のことを行います。

BinaryTree<int> *bt = new BinaryTree<int>();
bt->insert(100);
bt->insert(50);
bt->insert(101);

上記はうまくいきます、これまでのところとても良いです。

挿入メソッド/関数は、新しいノードの作成が行われる場所です。次に、次のそれぞれを (1 つずつ) 使用してみましたが、すべて segfault (コア ダンプ) が発生します。

delete bt->getRoot();

これにより、セグメンテーション違反が発生しました。私はそれから試しました

delete bt->getRoot()->getRight();

再びセグメンテーション。だから最後に試した

delete bt;

まだセグメンテーション違反

他のノードに到達できないためにメモリリークが発生するだけだと思っていましたが(valgrindで実行しています)、驚いたことに、valgrindがクラッシュし、gccとclangは-Wallを使用しても警告を出力しませんでした。これを正しく行う方法についてアドバイスが必要です。前もって感謝します。

4

3 に答える 3

3

これはあなたを台無しにするつもりです

~BinaryTreeNode<Type>() {
    delete left;
    delete right;
    delete parent;
}

左を削除し、次に右を削除します。良さそう。しかし、次の行のために失敗します。
ここで、親を削除します。次に、parent デストラクタが呼び出されて、左と右と親が削除されます。したがって、親を削除することで、自分自身で削除を呼び出しますが、他の誰かが削除を呼び出そうとしたため、すでに削除の最中です。決して終了しない再帰ループに入ることが唯一の問題ではありません。

試す:

~BinaryTreeNode<Type>() {
    delete left;
    delete right;
}

親は自分の子供を所有しているため、子供を削除する必要があります。
ただし、子は親を削除しないでください (子は親を所有していないため)。

C の手法ではなく C++ の手法を使用していれば、これは明らかでした (そして自動的に行われました)。見上げるstd::unique_ptr<>

PS。3 (C++11 では 5) のルールを実装していないため、オブジェクトにも根本的な欠陥があります。

于 2013-08-05T05:02:26.737 に答える