Seite 1 von 1

double free or coruption

Verfasst: 11. Februar 2011 12:35
von jerry42
Hallo,

ich stehe vor einem Problem, für das ich die beste Lösung suche.

Beim Beenden meines Programms wirft mir die Console den Hinweis aus:
*** glibc detected *** /home/repos/workspace/Application/Application: double free or corruption (!prev): 0x08400098 ***


Ich vermute zumindest wo das Problem liegt. Vielleicht kann mir das hier jemand bestätigen.

Ich arbeite mit einem QTreeWidget. Dort im Konstruktor füge ich viele QTreeWidgetItem ein, z.B. mit:
root = new QTreeWidgetItem(this);

Jedes Item stellt eine logische Verbindung mit einer anderen Struktur dar.
Diese Verknüpfungen werden in einer Map abgebildet. Diese Map wird im QTreeWiget verwaltet und sieht ungefähr so aus:
std::map< QTreeWidgetItem *, StrukturItem * > TreeMap;

beim Beenden des Programms bekomme ich nun den Fehler und ich vermute, dass der Desktruktor des QTreeWidgets, versucht alle QTreeWidgetItems zu löschen. Und bei der Auflösung der Map passiert das gleiche nochmal.

Bin ich da auf dem richtigen Weg? Wenn ja, ist QPointer dann eine mögliche Lösung? Oder spielt da das TreeWidget nicht mit?

Wäre für jeden Tipp dankbar.

Viele Grüße
jerry42

Verfasst: 11. Februar 2011 13:18
von franzf
jerry42 hat geschrieben:beim Beenden des Programms bekomme ich nun den Fehler und ich vermute, dass der Desktruktor des QTreeWidgets, versucht alle QTreeWidgetItems zu löschen. Und bei der Auflösung der Map passiert das gleiche nochmal.
Von der THeorie bist du auf dem richtigen Weg: Ein Objekt wird 2x zerstört. die Map word es aber nicht sein. Dort liegen nur Pointer, bei deren Zerstörung nicht der Destruktor der Objekte hinter dem Pointer zerstört werden, sondern nur der Zeiger selbst. Daraus kann also dein Problem nicht resultieren.
wahrscheinlicher ist, dass du irgendwo als Member ein Objekt als Value liegen hast (wird automatisch zerstört), du in einem anderen Objekt aber in einem Zeiger die Adresse dieses Objektes speicherst, und brav bei Nichgebrauch mit delet zerstörst. Geht das erste Objekt über den Jordan, kommt es zu dem "double free".
Oder noch besser (und schwerer zu debuggen): Zeiger auf globale Objekte.

Am besten gehst du mit deinem Debugger drüber und schaust, an welcher Stelle im Code das Problem auftritt, dann hast du einen Anhaltspunkt.

Verfasst: 11. Februar 2011 14:19
von pfid
Du kannst auch einfach mal valgrind laufen lassen, das zeigt dir beide Stellen (da wo es zum ersten mal und da wo es zum zweiten mal freigegeben wird).

Verfasst: 11. Februar 2011 15:21
von jerry42
hallo,

danke euch zwei erstmal.
mit valgrind bin ich nun draufgekommen, dass es mit dem zweiten argument der map zu tun hatte.
Dort lag ein Art AutoPointer. Ersetze ich es mit einem normalen Pointer, tritt der Fehler nicht mehr auf.

Hat da jemand eine Erklärung parat? :)

Viele Grüße
jerry42

Verfasst: 11. Februar 2011 19:33
von franzf
Hö? Ein StrukturItem* verhält sich anders als ein QSharedPointer<StrukturItem>. Ist das ein QScopedPointer, dann ist das etwas anderes. Kannst du mal bitte etwas mehr Code posten?

Verfasst: 16. Februar 2011 17:02
von jerry42
sorry für die lange Antwortzeit. Kam vorher einfach nicht dazu.

StrukturItem ist ein auto_ptr
Ist natürlich nicht StrukturItem*, sondern auto_ptr<StrukturItem>

In wie weit ändert das die Sache?

Danke
jerry42

PS: ich darf leider nicht mehr Code posten in dem Fall, sorry.

Verfasst: 16. Februar 2011 19:58
von franzf
Ui, wer ist auf diese geniale Idee gekommen? Google mal nach "std::auto_ptr in container". Die Kopier-Semantik von auto_ptr ist recht Destruktiv...