Я довольно новичок в общих указателях и пытаюсь удалить узел из графика. Когда я удаляю узел, входящие и исходящие ребра, хранящиеся в этом узле, будут удалены. Однако мне также необходимо удалить исходящий и входящий ребра (который является входящим и исходящим ребрами удалённого узла соответственно) узла, который ранее был подключен к удаленному узлу, который я называю узлом связывания.Удаление ребер для узла в ориентированном взвешенном графе, который использует интеллектуальные указатели
Приведенный ниже код показывает мои Graph объявления классов:
template <typename N, typename E> class Graph {
private:
struct Node;
struct Edge;
struct Node {
N val_;
int numEdges_;
int numIncomingEdges_;
std::set<std::shared_ptr<Edge>> edges_;
std::set<std::shared_ptr<Edge>> incomingEdges_;
Node() {}
Node(const N x) : val_{x} { numEdges_=0; }
void printNode(N n);
~Node();
void update();
};
struct Edge {
std::weak_ptr<Node> orig;
std::weak_ptr<Node> dest;
E val_;
Edge(std::shared_ptr<Node> o, std::shared_ptr<Node> d, E x);
Edge() {};
void printEdge();
~Edge();
};
..... Some code for node and edge iterators
private:
std::map< N, std::shared_ptr<Node> > nodes_;
};
Для класса, чтобы удалить узел:
template <typename N, typename E>
void Graph<N, E>::deleteNode(const N& node) noexcept {
auto findNode = nodes_.find(node);
if (findNode != nodes_.end()) {
// find the node which has incoming edges into the deleted node and delete its edges
for (auto edge: findNode->second->incomingEdges_) { // for each edge in node's incomingEdges_
// get the origin node of incoming edge to deleted node through dest.lock()
auto originNodeOfIncomingEdge = edge->dest.lock();
auto nodeVal1 = originNodeOfIncomingEdge->val_;
std::cout << "Print out value of origin node of incoming edge to deleted node: " << nodeVal1 << std::endl;
auto findLinkingNode1 = nodes_.find(nodeVal1);
std::cout << "size of edges_ in linking node before deleting its outgoing edge (which is the incoming edge of deleted node): " << findLinkingNode1->second->edges_.size() << std::endl;
auto findEdge = findLinkingNode1->second->edges_.find(edge);
findLinkingNode1->second->edges_.erase(findEdge);
std::cout << "size of edges_ in linking node after deleting its outgoing edge (which is the incoming edge of deleted node): " << findLinkingNode1->second->edges_.size() << std::endl;
--findLinkingNode1->second->numEdges_;
}
... similar code to above for deleting the node that has outgoing edges from deleted node going into it
findNode->second.reset(); // deletes managed object of the shared_ptr
nodes_.erase(findNode); // removes the node from the map container
}
}
Так что главное, что сбивает с толку меня есть эта часть, где я m пытается удалить ребро из цикла for, чтобы удалить ребро в связанном узле.
auto findEdge = findLinkingNode1->second->edges_.find(edge);
findLinkingNode1->second->edges_.erase(findEdge);
Но я продолжаю получать ошибки, связанные с shared_ptr. Первый связан с указателем:
test8c(2863,0x7fff78df2000) malloc: *** error for object 0x7ffda2403350: pointer being freed was not allocated
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
Ранее мой код для этой части findLinkingNode1->second->edges_.erase(edge);
без findEdge. Я смог скомпилировать без ошибок, но край не был удален.
Может ли кто-нибудь вести меня о том, как я могу удалить край из edge_ успешно? edge_ объявляется как std::set<std::shared_ptr<Edge>> edges_;
, как показано в классе Graph.
Как я могу удалить ребро на основе текущего кода? – iteong
Выполняя первые три шага в моем ответе, как я объяснил. –
Можно ли не менять декларации? Coz, если я это изменил, тогда мне придется изменить много других вещей в моем коде, который займет много времени. Мне просто нужно сделать то, что мне нужно сделать сейчас для реализации, и беспокоиться о рефакторинге позже (или изменении объявлений), если я получаю дополнительное время. – iteong