Это только гадать, но, учитывая код вы предоставляете ...
auto findEdge = findLinkingNode1->second->edges_.find(edge);
findLinkingNode1->second->edges_.erase(findEdge);
... Я бы сказал, что ваша проблема в том, что вы стираете edges_.end()
which is not allowed (вероятно, неопределенное поведение):
The iterator pos
must be valid and dereferenceable. Thus the end()
iterator (which is valid, but is not dereferencable) cannot be used as a value for 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, которые ...
Note that the comparison operators for shared_ptr simply compare pointer values; the actual objects pointed to are not compared.
... не сравнивает объекты, а только указатели. Поэтому, если указатели, используемые для вставки и поиска, не указывают на точно такое же (как в идентичном, не только «равном») объекте, вы зарегистрировались на наличие проблем.
Выше было предположение, но учитывая Ваш комментарий ...
findOrig->second->edges_.insert(std::make_shared<Edge>(Edge (findOrig->second, findDest->second, val)));
... делает это факт, так как там нет (почти) нет возможности достать указатель, возвращаемый make_shared
.
Внедрите класс сравнения для вашего набора, который сравнивает фактические объекты Edge
. (Избавление от указателей не так просто, потому что вы сказали, что Edge
является полиморфным)
Мораль: всегда проверяйте возможные ошибки.
Вы должны проверить возврат из поиска, если он не был успешным. Кроме этого, был ли указатель сохранен в общем указателе, который вы пытаетесь уничтожить, выделенном в куче? Как это было выделено? –
Являются ли «пограничные» полиморфными или содержат большие объемы данных? Если нет, то зачем вообще использовать общие указатели? Ценностная семантика может быть большой победой. –
Кромка, которая хранится в edge_, является общим указателем. Он преобразуется из края в общий указатель через std :: make_shared. «new» не использовался, чтобы сделать объект, на который указывают указатели, поэтому он не выделяется на кучу, я думаю.Что касается краев, да, они полиморфны, то общий шаблонный класс Graph используется с шаблоном функции для разных типов, а узловые и краевые структуры являются частью этого класса графа. – iteong