Pointer in map führt zu segfault
-
Hallo,
ich habe eine Klasse Node, und eine std::map<string, Node*>. Wenn ich dort Elemente per insert einfüge, und anschließend auf das Node-Objekt zugreifen will, bekomme ich einen segfault, da die Pointer schlichtweg auf 0 stehen.
Ich habe folgenden Code:
Node* node = new Node(source); // string: source map<string, Node*>::value_type nodePair(source, node); mymap.insert(nodePair); // ... mymap["foo"]->getName(); // führt zu segfault, da der value auf 0x0 steht.Ich habe dazu folgendes gefunden: https://stackoverflow.com/questions/10333854/how-to-handle-a-map-with-pointers
Mir ist jedoch noch nicht ganz klar, warum insert nicht den entsprechenden Konstruktor aufruft. Könnte mir jemand nettes hier erklären, was da genau passiert?
Ich habe den Node(string), Node(), Node(const Node&)-Konstruktor, sowie operator(const Node&) mit cout-Anweisungen ausgestattet, jedoch wird bei der insert-Variante nur der normale Node(string)-Konstruktor aufgerufen.
Vielen Dank!
-
Musst du unbedingt Pointer auf Node speichern?
-
Nathan schrieb:
Musst du unbedingt Pointer auf Node speichern?
Ja, leider. Ist eine Vorgabe.
-
Eigentlich gibt der StackOverflow Artikel dazu auch etwas. Denn jede Antwort da hinterfragt, warum Pointer genutzt werden anstatt von Objekten.
Ausser die letzte Antwort, die schlägt die Ptr_Container von Boost vor, in dem Fall die boost::ptr_map.
-
Wie gesagt, Node als Pointer ist eine Vorgabe der Aufgabe (der Uni). Ich würde das grundsätzlich anders machen, aber irgendwie mögen Professoren es nicht, wenn man die Vorgaben ändert -- selbst wenn sie schlichtweg dämlich sind.
Ich möchte nur verstehen, warum bei einem insert der Pointer nicht kopiert wird.

-
Wenn beim []-Operator der Eintrag in der Map noch nicht existiert, dann wird der Standardwert dafür eingetragen (bei einem Zeiger also der Nullpointer).
Wenn du explizit abfragen möchtest, ob der Wert in der Map schon existiert, dann benutze map::find.
-
Der Eintrag existiert ja; ich habe mir mit gdb anzeigen lassen, wie das aussieht:
(gdb) p dg.nodeMap $1 = std::map with 17 elements = {["Bad_Essen"] = 0x0, ["Bad_Iburg"] = 0x0, ["Bissendorf"] = 0x0, ["Borgholzhausen"] = 0x0, ["Bramsche"] = 0x0, ["GMH"] = 0x0, ["Glandorf"] = 0x0, ["Ibbenbueren"] = 0x0, ["Ladbergen"] = 0x0, ["Lengerich"] = 0x0, ["Melle"] = 0x0, ["Neuenkirchen"] = 0x0, ["Osnabrueck"] = 0x0, ["Osterkappeln"] = 0x0, ["Osterkappen"] = 0x0, ["Wallenhorst"] = 0x0, ["Westerkappeln"] = 0x0}Das Erstellen des Eintrags ist möglich, jedoch wird der Pointer nicht übernommen, wenn ich per insert einfüge. Wenn ich per
nodeMap[source] = new Node(source)einfüge, dann geht's.
Ich will einfach nur verstehen, warum insert hier so anders funktioniert und den Zeiger nicht mitkopiert.

-
Ach... Jetzt fällt mir was auf:
ich nutze zuvor if(nodeMap[source] == 0) um zu überprüfen, ob das Element existiert. Damit wird es erzeugt, der Pointer auf 0 gesetzt und entsprechend funktioniert insert nicht mehr, weil der Index schon besteht.
Ich hätte über eure Antwort mehr nachdenken sollen. Danke!!

-
