2017-12-07 9 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; 
} 

공지 것을 : 여기에 당신이 무엇을 게시했다.

제 2 if 문이 있어야한다 : 당신의 for 루프 내 그렇지 않으면

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; 
} 

하지 break 등을 계속하고, 다음에 검색하는 아이는 일치하지 않을 것입니다. 당신이 for 루프가 생략되기 때문에 및 어떤 아이들이없는 일치하는 이름이없는 노드 을 통해 검색하면 방법 당신의 searchMember 기능 NULL에 결과를 구조화되어

주 (자녀가없는 반환 반복하기 위해). 따라서 많은 NULL 포인터가 parent에 할당되고 결국 addMember이됩니다.

+0

Thx 너무 많이, 그것은 나쁜 실수입니다. 나는 너무 부주의합니다. 이것이 잘못 된 곳이 아니라는 것이 유감입니다. 루트 노드에 요소를 추가하려고 할 때 문제가 발생하여 검색 기능이 올바른 주소를 반환합니다. 여전히 문제에 대해 혼란스러워합니다. 모두 고맙습니다 .1 – Dinghow