2016-04-07 10 views
0

unordered_map要素への参照を削除しようとしています。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); 
    } 

現在、私はこのanswerに基づいてポインタを削除していますが、私それを担当する私のクラスの一部は、このようになりますセグメンテーションエラーがdeleteと一致しています。この同じ答えでは、smart pointersを使用するための提案もあります。私はここでの使用についてはわかりませんshared_ptr。ここには複数の辺に1つのノードオブジェクトへのポインタがあるというオプションがありますが、グラフのunordered_mapからノードeraseを実際に実行すると実際に何が起こりますか?最後のif/else条件が間違っているのですか?私はそれを完全に理解していません。

EDIT:

私はそれが削除される前に、ノードの名前を表示したいと仮定します。私はedge.from->to_deleteを経験してきたように、何らかの形であるため、時にはtrueを返し、ヌルポインターを防ぐ機能はありません、今

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); 
} 

:だから私はそのような何かを持っています。私が試したことは条件が次のように変化した場合です:

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

しかし、それはまったく助けになりません。

+0

一度に一つの質問をします。プログラムが正常に動作しない場合は、MCVE – Slava

+0

@Slavaは接続されていませんか?私は別の質問だとは思わない。 – sebap123

+0

私はすでに "unordered_mapでオブジェクトへのポインタを削除する"についてのあなたの質問に、あなたのコードが期待どおりに動作しない理由について別の質問です。まず第一に、それに答えるための十分な情報がありません。 – Slava

答えて

0

は現在、私はあなたがその答えを理解していなかった

この回答に基づいてポインタを削除しています - あなたは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 

または削除コールする必要があります。

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); 
} 
+0

ありがとうございます。この場合、これは適用されないことに気づいていませんでした。この場合、「新」は暗黙のうちに呼び出されたと私は考えました。だから、あなたはこのポインタを削除することをお勧めしますか? – sebap123

+0

あなたはそれらを削除しないことをお勧めします。それに応じてロジックに変更してください(消去された要素はもう指されません) – Slava

+0

例えば 'erase()'の後に 'edge.from'がある種のごみを指し示します。私は 'edge.from = nullptr;'のようなことをしてはいけませんか?なぜこのノードから名前を読み込むのが安全かどうかを知るだろうか? – sebap123

関連する問題