我是std :: shared_ptr和std :: set的新手。对于以下代码,我想知道如何从边_删除边。
edges_声明为std::set<std::shared_ptr<Edge>> edges_;
,我想删除存储在std :: set中的共享指针引用的边。我的部分代码在这里,但似乎有问题。
auto findEdge = findLinkingNode1->second->edges_.find(edge);
findLinkingNode1->second->edges_.erase(findEdge);
错误:
test8c(3034,0x7fff78df2000) malloc: *** error for object 0x7f8553403350: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
考虑到共享指针存储在std :: set中,我如何从edge_中删除边缘,这是通过共享指针管理的?
答案 0 :(得分:1)
它只是猜测,但考虑到你提供的代码......
auto findEdge = findLinkingNode1->second->edges_.find(edge);
findLinkingNode1->second->edges_.erase(findEdge);
...我说你的问题是你正在删除edges_.end()
which is not allowed(可能是未定义的行为):
迭代器
pos
必须有效且可解除引用。因此end()
迭代器(有效但不可解除引用)不能用作pos的值。
如果在集合中找不到给定的findEdge
,则变量edges_.end()
将等于edge
。要查找元素,std::set
使用Compare
对象,其类型通过第二个模板参数定义...
std::set<std::shared_ptr<Edge>> edges_;
...您没有指定,因此它默认为std::less<std::shared_ptr<Edge>>
,后者又调用the operator<
of the shared pointer,其中...... {/ p>
请注意,shared_ptr的比较运算符只是比较指针值;指向的实际对象不进行比较。
...不比较对象而只比较指针。因此,如果用于插入和搜索的指针未指向完全相同的(与相同的,不仅仅是#34;相等的#34;)对象,那么您已注册麻烦。
以上是一个猜测,但鉴于你的评论......
findOrig->second->edges_.insert(std::make_shared<Edge>(Edge (findOrig->second, findDest->second, val) ));
...这是事实,因为(几乎)无法掌握make_shared
返回的指针。
解决方案:为您的集合实现比较类,以比较实际的Edge
对象。 (摆脱指针并不是那么简单,因为你说Edge
是多态的)
士气:始终测试可能的错误情况。