0

I have a std::set declared as the following:

std::set<std::shared_ptr<Edge>> edges_;

I want to remove a shared_ptr, effectively one of the edges stored in edges_, from the set. It does go into the if loop where it prints that it has found the edge, but I can't erase the shared_ptr from the set.

auto findEdge = findLinkingNode1->second->edges_.find(edgeLink);
if (findEdge != findLinkingNode1->second->edges_.end()) {

    std::cout << "found edgeLink in edges_ so erasing it!" << std::end;
    findLinkingNode1->second->edges_.erase(findEdge);
    } else {
    std::cout << "edgeLink not found in edges_!!" << std::endl;
    }

I think that it has problem erasing because the set's erase method uses a const_iterator, and since this is a set of shared_ptr, it is trying to erase a const_iterator pointing to a shared_ptr which is pointing at a shared object. Not sure what I need to do to successfully delete the edge from edges_.

The complete class I'm working on:

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_

            std::cout << "For each incoming edge in node to be deleted (incoming edge " << edge->val_ << ")" << std::endl;

            // 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;


            for (auto edgeLink: findLinkingNode1->second->edges_) {
            std::cout << "An outgoing edge in origin node " << nodeVal1 << " of incoming edge to deleted node (outgoing edge " << edgeLink->val_ << ")" << std::endl;


                auto findEdge = findLinkingNode1->second->edges_.find(edgeLink);
                std::cout << "edgeLink->val_ is: " << edgeLink->val_ << " and edge->val_ is: " << edge->val_ << std::endl;
                std::cout << "edgeLink->orig.lock()->val_ is: " << edgeLink->orig.lock()->val_ << " and edge->orig.lock()->val_ is: " << edge->orig.lock()->val_ << std::endl;
                if (edgeLink->val_ == edge->val_) {
                std::cout << "they are the same, so try to erase...." << std::endl;

                    // if can find edge in edges_
                    if (findEdge != findLinkingNode1->second->edges_.end()) {
                        std::cout << "found edgeLink in edges_ so erasing it!" << std::endl;

                        findLinkingNode1->second->edges_.erase(findEdge);
                    } else {
                        std::cout << "edgeLink in edges_ not found!!" << std::endl;
                    }

                }

            }


            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_;

        }

        findNode->second.reset(); // deletes managed object of the shared_ptr
        nodes_.erase(findNode); // removes the node from the map container

    }
}

The graph class declarations:

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();
        };
iteong
  • 715
  • 3
  • 10
  • 26
  • You could just call [`erase`](http://en.cppreference.com/w/cpp/container/set/erase) (passing it the value, not the iterator) if your goal is to simply remove the item. `erase` will return 0 if the item wasn't contained in the set, or 1 if the item was in the set and was erased. – Cornstalks Sep 18 '16 at 03:37
  • I tried erase(edgeLink) but it doesn't work – iteong Sep 18 '16 at 03:41
  • Then you need to post your **complete** code (but trimmed of unnecessary steps!). [A Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve). – Cornstalks Sep 18 '16 at 04:00
  • I tried both erase(findEdge) and erase(edgeLink), but both got segmentation fault. So the erasing of the from the std::set> edges_ is unsuccessful... – iteong Sep 18 '16 at 04:37

0 Answers0