segmentation fault bei std::set insert eines pointers

pointhi

Erfahrenes Mitglied
Hy,

ich arbeite gerade an einem etwas spezielleren system, bei dem ich unter anderem eine objekt-baum-struktur mithilfe eines xml-files erzeugt.

Um rechenleistung, und um vor allem komplexen code zu vermeiden will ich im root-node eine dynamische array mit pointern zu einem speziellen objekten erzeugen( Wenn das objekt instanziert wird trägt es sich automatisch in diese liste ein, und wenn der destruktor aufgerufen wird auch wieder aus).

Das Problem ist nur, sobald ich den pointer mittels insert zu den container hinzufügen will, stürzt das programm wegen speicherverletzung ab, obwohl das in meinem fall verwendete std::set genau so etwas eigentlich verhindern sollte.

Der Code ist OS, weshalb ich hier einfachhalber verlinke:

Das ist der code-teil, in welchem die Objekte ein- und ausgetragen werden können:

https://github.com/pointhi/OpenSens...1ce7a15f771d7/include/OssRootNode.hpp#L68#L83

Hier werden die entsprechenden funktionen aufgerufen:

https://github.com/pointhi/OpenSens...ce7a15f771d7/src/sensor/OssSensor.cpp#L24#L40

Damit man sich wenn nötig leichter zurechtfindet hab ich unter anderem auch eine online doku

Was ich vermute ist, dass ich bei den aufrufenden funktionen einen denkfehler gemacht habe. Ich musste leider einen const_cast durchführen, da der this zeiger meines wissens leider eine const maskierung aufweißt.

Ich hoffe ihr könnt mir helfen

mfg, pointhi
 
Guten Morgen,

bist du schonmal mit einem Debugger über dein Programm gegangen und hast geprüft ob "_sensorObject" beim Aufruf von "AddSensor" denn wirklich NULL ist? Vielleicht liegt der Fehler ja auch woanders. Bei einem schnellen Check gerade konnte ich zumindest nichts verdächtiges sehen.

Und ich kann mir eigentlich nicht vorstellen, dass der this Zeiger eine const-Maskierung trägt. Ausserdem rufst du doch das "const_cast" auf der Rückgabe von GetRootNode() auf und nicht auf dem "this" Zeiger.

Gruß,
Wolf
 
der pointer darf ja nicht null sein, da ich dann ja keine referenz in dem container hätte, mittels dem ich die klasse direkt aufrufen könnte. Der Container selber sollte eigentlich den nötigen platz für den pointer reservieren und ihn dann dort ablegen.
Ich hab eine fast gleiche konstruktion in einer anderen klasse mittels shared_ptr, die in diesesem fall aber diverse probleme verursachen würde (das objekt könnte zur laufzeit nicht gelöscht werden, etc.)

Debuggen müsste ich mir mal anschauen, mir hat bisher das debuging mittels textausgaben gereicht, und hab deshalb noch keine erfahrung mit richtiger debugsoftware gemacht.

mfg, pointhi
 
Ich weiss nicht genau wie std::set intern mit NULL Pointer verfährt, aber du kannst im Sinne einer defensiven Programmierung in deiner AddSensor Methode ja vorher schon einmal abfragen ob der übergebene Pointer NULL ist und gegebenenfalls eine Error-Message auswerfen.

Aber ich denke auch, dass das Problem nicht in dem übergebenen Parameter liegt.

Debuggen per Text-Ausgabe habe ich früher auch meistens genutzt und es ist auch immernoch teilweise ein wichtiger Bestandteil. Aber du solltest dich auch definitiv mit den Debugging-Tools auseinander setzen. Die erleichtern das Auffinden bestimmter Fehler schon um einiges und daher lohnt es sich, sich damit genauer zu befassen.

Gruß,
Wolf
 
[...] shared_ptr, die in diesesem fall aber diverse probleme verursachen würde (das objekt könnte zur laufzeit nicht gelöscht werden, etc.)

Stichwort: std::weak_ptr

Die folgende Abfrage ist irgendwie merkwürdig:
C++:
            if (!rootNode) {
                rootNode->AddSensor(this);
            }

Mit anderen Worten: wenn rootNode == nullptr, dann rufe nullptr->AddSensor(this) auf, was im Code dann heisst nullptr->sensorList.insert(_sensorObject). Logischerweise fuktioniert das nicht.

Zu std::set mit nullptr. Das ist kein Problem, das set ist absolut nicht daran interessiert, was die übergebenen Werte für eine kontextuale Bedeutung haben. Ein nullptr wird einfach für die Sortierung als 0 betrachtet.
 
ich glaub ich hab das problem gefunden.

this->GetRootNode liefert die adresse des eigenen objektes zurück, da noch kein elternobjekt definiert ist. Mal schauen, wie ich das in den konstrukor am besten implementiere.

Der Ablauf für das erstellen eines neuen punktes ist derzeit wie folgt:

  1. Erstelle Objekt in einem shared_ptr -> Konstruktor wird aufgerufen
  2. Kopiere es als child element in die dynamische array
  3. setze adresse zu eltern-objekt -> Ab hier würde der konstruktor erst richtig funktionieren


mfg, pointhi

EDIT:

hab es gelöst, zumindestens auf konstruktorebene. Beim destruktor funktioniert es komischerweise nicht, weshalb ich unter anderem deswegen, die implementierung auf std::weak_ptr ändern werde.

thx, pointhi
 
Zuletzt bearbeitet:
Zurück