使用vector的push_back()函数后,为什么元素会消失

时间:2017-12-07 11:01:40

标签: c++ vector

我正在尝试在类中使用std::vector来实现多路树。

每当我想在成员中添加子项时,我都使用函数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 个答案:

答案 0 :(得分:0)

我怀疑familyTree::searchMember功能有问题。以下是您发布的内容:

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

请注意,找到正确的节点后,没有方法可以设置flag = true

第二个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,因此它会继续,并且您搜索的下一个孩子将保证不匹配。

请注意,如果您搜索的节点没有匹配的名称,则searchMember功能的结构方式会导致NULL被返回没有任何孩子因为跳过了for循环(没有孩子要迭代)。因此,您最终会在NULL中将parent指针分配给addMember