正在删除指向无序映射中对象的指针

Deleting pointer to object in unordered_map

本文关键字:对象 指针 映射 无序 删除      更新时间:2023-10-16

我正在尝试删除对unordered_map元素的引用。我的课程中负责这一点的部分看起来是这样的:

class Edge:
{
    public:
        Node* from;
        Node* to;
}
class Node:
{
    public:
        std::string name;
        bool to_delete;
}
class Graph:
{
    public:
        std::unordered_map<std::string, Node> nodes;
        std::vector<Edge> edges;
}

在我的主文件代码中,我正在做这样的事情:

    Node n("My node");
    graph.nodes.insert({n.name,n});
    edge.from = &graph.nodes[n.name];
    // Some other stuff
    for(auto& edge : graph.edges)
    {
        if(edge.from->to_delete)
        {
            graph->nodes->erase(edge.from->name);
            delete edge.from;
            edge.from = NULL;
        }
        if(edge.to->to_delete)
        {
            graph->nodes->erase(edge.to->name);
            delete edge.to;
            edge.to = NULL;
        }
        if(edge->from && edge->to)
            DoSomethingWithNodes(edge->from, edge->to);
        else
            removeEdge(edge);
    }

目前,我正在删除基于这个答案的指针,但我在delete行上遇到了分段错误。在同一答案中,还建议使用smart pointers。我不确定是否使用这里的shared_ptr。我在这里有一个选项,即多条边将有指向一个节点对象的指针,但当我从图的无序映射中erase节点时,实际会发生什么。如果最后一个if/else条件指向那里,我会得到false吗?我不完全理解。

编辑:

假设我想在删除节点之前显示它的名称。所以我会有这样的东西:

for(auto& edge : graph.edges)
{
    if(edge.from->to_delete)
    {
        printf("Node to delete: %s",edge.from->name.c_str());
        graph->nodes->erase(edge.from->name);
        edge.from = nullptr;
    }
    if(edge.to->to_delete)
    {
        printf("Node to delete: %s",edge.to->name.c_str());
        graph->nodes->erase(edge.to->name);
        edge.to = nullptr;
    }
    if(edge->from && edge->to)
        DoSomethingWithNodes(edge->from, edge->to);
}

现在,没有针对空指针的保护,因为正如我所经历的,edge.from->to_delete有时会返回true。我所尝试的是将条件更改为:

if(edge.from && edge.from->to_delete)

但这一点帮助都没有。

目前我正在删除基于这个答案的指针

你不明白这个答案——你只能用new创建的delete对象来控制它们的所有权,在你的情况下,对象是由std::unordered_map管理的,因为你通过值而不是指针来存储它们。所以在这种情况下,您不能在这些对象上调用delete,而调用std::unordered_map::erase()就足够删除对象了。

示例:

std::unordered_map<std::string,Someclass> mymap;
mymap.insert( std::make_pair( "foobar", Someclass() ); // adding object by value
...
mymap.erase( "foobar" ); // object managed by map and will be deleted

或者当您需要调用delete时:

std::unordered_map<std::string,Someclass *> mymap;
mymap.insert( std::make_pair( "foobar", new Someclass() ); // adding object by pointer
...
auto f = mymap.find( "foobar" );
if( f != mymap.end() ) {
    delete f->second; // you need to delete object that you created by new before
    mymap.erase( f );
}