从edges_中删除边缘,声明为std :: set <std :: shared_ptr <edge>&gt; edges_;

时间:2016-09-17 16:29:50

标签: c++ graph iteration shared-ptr stdset

我是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_中删除边缘,这是通过共享指针管理的?

1 个答案:

答案 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是多态的)

士气:始终测试可能的错误情况。