double free or coruption

Alles rund um die Programmierung mit Qt
Antworten
jerry42
Beiträge: 126
Registriert: 9. Oktober 2008 10:48

double free or coruption

Beitrag 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
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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.
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag 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).
jerry42
Beiträge: 126
Registriert: 9. Oktober 2008 10:48

Beitrag 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
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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?
jerry42
Beiträge: 126
Registriert: 9. Oktober 2008 10:48

Beitrag 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.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag 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...
Antworten