2016-07-01 8 views
-1

ツリー構造を書き、ツリー内のノードを探すための基本的な検索機能を作成しました。ツリー自体は、センチネルノードを使用してすべての端(ルートの親、葉の子)をマークし、検索はノードを介して単純に繰り返され、マッチまたはセンチネルノードにヒットします。検索機能は、ツリーのインスタンス上で呼び出すと正常に機能しますが、ツリーが別のクラスのデータメンバーである場合には機能しません。次のコードでは、 "t.search(1)"は機能しますが、 "embedded_tree.t.search(1)"は無限ループに陥ります。クラスメンバ関数は正常に動作しますが、別のクラスのデータメンバとして呼び出されると無限ループに陥ります

embedded_tree.t.search()の呼び出しが行われたとき、 "& sentinel"の内容はセンチネルノードを正しく指していますが、新しいポインタのようですroot、sentinel.parent、およびsentinel.childの内容と等価ではありません。ここから私は立ち往生し、それを呼び出す方法がわからないので、&のセンチネルは、ツリーの構築時に作成されたポインタと一致します。

#include <iostream> 

struct NODE { 
    int key; 
    NODE* parent; 
    NODE* child; 
    NODE() : key(0), parent(NULL), child(NULL) {}; 
}; 

struct TREE { 
    NODE sentinel; 
    NODE* root; 

    TREE() 
    { 
     sentinel = *new NODE; 
     sentinel.parent = &sentinel; 
     sentinel.child = &sentinel; 
     root = &sentinel; 
    } 

    NODE* search(int k) 
    { 
     NODE* x = root; 
     while (x != &sentinel) 
     { 
      if (x->key == k) return x; 
      x = x->child; 
     } 
     return &sentinel; 
    } 
}; 

struct A { 
    TREE t; 

    A() : t(*new TREE()) {}; 
}; 

int main() 
{ 
    TREE t; 
    t.search(1); 

    A embedded_tree; 
    embedded_tree.t.search(1); 
} 
+1

'sentinel = * new NODE;'は良い考えではありません。 – alain

+2

't(* new TREE())' - なぜあなたはこれをやっていますか?必要な場合を除いてポインタを割り当てずにポインタを使用しない限り、 'new'は使用しません(ヒント:ここでは必要ではなく、メモリリークを引き起こします)。 –

+0

'embedded_tree.t.search(1);'関数呼び出しをトレースすると、デバッガはあなたに何を伝えますか? –

答えて

0

ダイナミックメモリ割り当てとスタック割り当てが混乱しています。あなたがするとき

sentinel = *new NODE 

悪いことが起こります。スタック上にNODE sentinelのメモリが割り当てられた後、演算子のNODEの場合、割り当てはsentinelの変数に割り当てられ、new演算子で作成されたメモリは失われます。あなたは代わりにポインタを使用するようにコードを書き換えて、デストラクタを追加し、しかしこの

#include <iostream> 

struct NODE { 
    int key; 
    NODE* parent; 
    NODE* child; 
    NODE() : key(0), parent(NULL), child(NULL) {}; 
}; 

struct TREE { 
    NODE* sentinel; 
    NODE* root; 

    TREE() 
    { 
     sentinel = new NODE; 
     sentinel->parent = sentinel; 
     sentinel->child = sentinel; 
     root = sentinel; 
    } 

    ~TREE() { 
     if (NULL != sentinel) { 
      delete sentinel; 
      sentinel = NULL; 
      root = NULL; 
     } 
    } 

    NODE* search(int k) 
    { 
     NODE* x = root; 
     while (x != sentinel) 
     { 
      if (x->key == k) return x; 
      x = x->child; 
     } 
     return sentinel; 
    } 


}; 

struct A { 
    TREE* t; 

    A() : t(new TREE()) {}; 
    ~A() { 
     if (NULL != t) { 
      delete t; 
      t = NULL; 
     } 

    } 
}; 

int main() 
{ 
    TREE t; 
    t.search(1); 

    A embedded_tree; 
    embedded_tree.t->search(1); 
} 

のようなもの、私たちはC++の話をしているので、あなたが慣れるの後、私はスマートポインタやコンテナに見て、あなたをお勧めしたいはずです手動メモリ管理が可能です。

関連する問題