如何解决在向量中存储对象时的不良行为
#include <iostream>
#include <vector>
#include <algorithm>
#include <unordered_map>
using namespace std;
struct Node {
string name;
vector<Node> nodes;
Node(const string & name) : name(name) {}
~Node() {
cout << "release " << name << endl;
}
};
Node root {"A"};
unordered_map<string,Node*> m;
void add_child(const string & parent,const string & child) {
if (!m.count(parent)) return;
auto & p = *m[parent];
cout << "add " << parent << endl;
// Here is the bug
p.nodes.emplace_back(child);
m[child] = &p.nodes.back();
cout << "add done " << parent << endl;
}
int main() {
m["A"] = &root;
vector<string> edges {"A","B","A","D","E"};
for (int i = 0; i < edges.size(); i += 2) {
add_child(edges[i],edges[i + 1]);
}
}
我正在构建一棵树,其中子节点直接存储为对象类型而不是指针类型。
每当我插入一个新节点时,我都会使用unordered_map来存储名称和指向对象的指针的映射。
程序尝试访问add_child
函数中插入的节点时,该程序运行失败并引发BAD_ACCESS异常。最后,事实证明这是由于B节点已被删除的事实所致。我的问题是:什么时候发生?
输出为:
add A
add done A
add A
release B
add done A
add B
Exception: EXC_BAD_ACCESS (code=1,address=0x100000010)
解决方法
在调用类似函数push_back的向量自动扩展/重新分配较大的空间之后,元素的地址将更改。
一种解决方案是将new
分配的地址存储在向量中,并在父节点解构后将其全部删除。例如
struct Node {
string name;
vector<Node*> nodes;
~Node() {
for (auto pch : nodes)
delete pch;
}
};
root.nodes.push_back(new Node("child node"));
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。