I'm new to std::shared_ptr and std::set. For the following code, I want to know how I can delete the edge from edges_.
edges_ is declared as std::set<std::shared_ptr<Edge>> edges_;
and I want to delete the edge referenced by the shared pointer stored in the std::set. My code for the part is here, but there seems to be problem.
auto findEdge = findLinkingNode1->second->edges_.find(edge);
findLinkingNode1->second->edges_.erase(findEdge);
Error:
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
How can I delete the edge from edges_, which is managed through shared pointers, considering that the shared pointers are stored in a std::set?
It's just guessing, but given the code you provide ...
auto findEdge = findLinkingNode1->second->edges_.find(edge);
findLinkingNode1->second->edges_.erase(findEdge);
... I'd say your issue is that you're erasing edges_.end()
which is not allowed (probably undefined behavior):
The iterator
pos
must be valid and dereferenceable. Thus theend()
iterator (which is valid, but is not dereferencable) cannot be used as a value for pos.
The variable findEdge
will be equal to edges_.end()
if the given edge
was not found in the set. To find an element, std::set
uses a Compare
object whose type is defined via the second template parameter ...
std::set<std::shared_ptr<Edge>> edges_;
... which you didn't specify, thus it's defaulting to std::less<std::shared_ptr<Edge>>
which in turn calls the operator<
of the shared pointer, which ...
Note that the comparison operators for shared_ptr simply compare pointer values; the actual objects pointed to are not compared.
... does not compare the objects but only the pointers. Therefore, if the pointers used for inserting and searching are not pointing to exactly the same (as in identical, not only "equal") object, you've signed up for trouble.
The above was a guess, but given your comment ...
findOrig->second->edges_.insert(std::make_shared<Edge>(Edge (findOrig->second, findDest->second, val) ));
... makes it a fact, as there's (almost) no way to get hold of the pointer returned by make_shared
.
Solution: Implement a compare class for your set that compares the actual Edge
objects. (Getting rid of the pointers isn't that straightforward because you said that Edge
is polymorphic)
Morale: Always test for possible error conditions.