2017-12-07 4 views
0

クラス内でstd::vectorを使用して多方向ツリーを実現しようとしています。ベクトルのpush_back()関数を使用した後に要素が消える理由

メンバーの上に子を追加するたびに、私は関数addMemberを使用します。私はこのプログラムをデバッグするためにVS2017を使用しています。この関数のスコープでは、親の子ベクトルは実際にはpush_back()で要素を追加しますが、関数を終了すると、ベクトルのアドレスが変更され、追加した要素は消えます。

は、ここに私のコードです:

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

using namespace std; 

class member { 
public: 
    string name; 
    member* parent; 
    vector<member*> children; 
    member(string m_name,member* m_parent):name(m_name),parent(m_parent){} 
}; 

class familyTree { 
private: 
    member ancestor; 
public: 
    member* getAncestor() { return &ancestor; } 
    familyTree(member& m_ancestor):ancestor(m_ancestor){} 
    member* searchMember(string name,member* node,bool& flag); 
    void addMember(string name, int children_number,vector<string>& children_name); 
}; 

member* familyTree::searchMember(string name, member* node,bool& flag) { 
    member* find = NULL; 
    if (node) { 
     if (node->name == name) 
      find = node; 
     else { 
      if (!flag) { 
       for (auto iter = node->children.begin(); iter != node->children.end(); iter++) { 
        find = searchMember(name, *iter, flag); 
        if (flag) 
         break; 
       } 
      } 
     } 
    } 
    return find; 
} 

void familyTree::addMember(string name,int children_number,vector<string>& children_name) { 
    bool flag = false; 
    member* parent = searchMember(name, getAncestor(), flag); 
    for (auto i : children_name) { 
     member* child = new member(i,parent); 
     parent->children.push_back(child); 
    } 
} 
+1

あなたは 'addChild()'メソッドはありません。あなたは 'addMember()'を意味しましたか?人々が理解できるように一貫した質問を書いてください。また、あなたは本当にその新しいメンバーをどこかで削除しようとしていますか?そして、あなたは何を意味していますか?「ベクターのアドレスが変わり、私が加えた要素は消える」_あなたが期待していたものと比べて、これをテストし、得られた出力の例を表示できますか? –

+0

Thx、私はそれを修正しました。私が書いた関数では決して削除しません。シングルステップデバッグモデルでは、新しいメンバがベクターに追加されていることを確信していますが、addMember関数を終了すると、私が操作したベクトルは変更され、その中の要素は消去されます。 – Dinghow

+0

くそー、それはexeでうまくいったことが分かりました、要素は消えることはありませんが、私はシングルステップデバッグモデルを使用する場合、それを行うでしょう。 – Dinghow

答えて

0

私はfamilyTree::searchMember機能に問題があると思われます。あなたが正しいノードを見つけたらflag = trueを設定する方法はありませんでした

member* familyTree::searchMember(string name, member* node, bool& flag) { 
    member* find = NULL; 
    if (node) { 
     if (node->name == name) 
      find = node; 
     else { 
      if (!flag) { 
       for (auto iter = node->children.begin(); iter != node->children.end(); iter++) { 
        find = searchMember(name, *iter, flag); 
        if (flag) 
         break; 
       } 
      } 
     } 
    } 
    return find; 
} 

お知らせこと:ここではあなたが投稿何でした。

第二if文は次のようになります。

if (node->name == name) { 
    find = node; 
    flag = true; 
} 

そうでなければ、あなたのforループ、

for (auto iter = node->children.begin(); iter != node->children.end(); iter++) { 
    find = searchMember(name, *iter, flag); 
    if (flag) 
     break; 
} 

以内に成功した検索があった場合でも、forループはそれがないbreakとそうあなたが検索した次の子供は一致しないことが保証されています。あなたはforループがスキップされているので、一致する名前とはどんな子供たちにを持っていない持っていないノードて検索した場合の方法は、あなたのsearchMember機能がNULLで構造化された結果が返されていることを

注意(子供がいません反復する)。したがって、多くのNULLポインタがparentに割り当てられて、最終的にはaddMemberになります。

+0

Thxそんなに、それは悪い間違いです。私は非常に不注意です。これが間違っている場所ではないことは残念です。ルートノードに要素を追加したいときに問題を発見したので、検索機能が正しいアドレスを返します。私の問題についてはまだ混乱しています皆さん、同じことをありがとうございます1 – Dinghow

関連する問題