Problem mit Zeigern in einer Liste

Alles rund um die Programmierung mit Qt
Antworten
Thorsten
Beiträge: 55
Registriert: 29. Dezember 2004 22:47
Wohnort: Aachen

Problem mit Zeigern in einer Liste

Beitrag von Thorsten »

Hallo zusammen,

ich habe ein kleines Problem und bitte um Hilfe.

Ich habe folgende Datenstruktur:

Code: Alles auswählen

QList<Entry*> listEntries;
welche in einer Klasse als Member enthalten ist.
Im Destruktor will ich nun den Speicher wieder frei geben, bekomme aber immer einen Laufzeitfehler. (Windoof will nach Hause telefonieren.)

Code: Alles auswählen

virtual ~List()
{
    foreach (Entry* e, listEntries)
        if(e)
            delete e;
}
Liegt es vielleicht am Schlüsselwort foreach, oder an der QList selber? Ich füge definitiv keine Nullzeiger ein, was durch das if ja eh abgefragt wird.
Wenn ich die drei Zeilen auskommentiere läufts. Der Konstuktor von Entry lasse ich automatisch erzeugen (ich habe ihn nicht implementiert), da nur noch statische Elemente genutzt werden.

Gruß
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Es ist nicht wichtig, was Windows sagt, sondern was dein Debugger sagt...
Thorsten
Beiträge: 55
Registriert: 29. Dezember 2004 22:47
Wohnort: Aachen

Beitrag von Thorsten »

Mein Debugger meldet eine Zugriffsverletzung beim delete. s ist gleich 0x3d4be8. std::list tut es auch nicht.

Kann es vielleicht daran liegen, das die Zeiger nur auf eine Basisklasse zeigen. Die Destruktoren sind alle virtuel, werden ja aber auch erst garnicht aufgerufen.

Die Adressen stimmen. Ich erzeuge zwei Objekt, trage die Adressen in die Liste ein und will sie später wieder zerstören. Leider ohne erfolg.
Dateianhänge
IniTest.zip
Ich habe die wichtigsten Zeilen mal zusammengefasst.
(1.95 KiB) 169-mal heruntergeladen
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Qt bringt was eigenes mit.
qDeletAll()
Abgesehen davon:
Die Adressen stimmen. Ich erzeuge zwei Objekt, trage die Adressen in die Liste ein
Wie sieht das dann aus? Zeig mal Code :)

//edit:
sry, seh grad erst dass du bei deinem letzten Post ja was angehangen hast...
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Du löscht die Zeiger der p_listSections aber nicht den Inhalt der Liste und läufst dann nochmal über die Liste drüber und löscht die Einträge nochmal...

Einfach Abhilfe wäre in diesem Fall das qDeleteAll(), da es Inhalt und die Elemente, auf die die Zeiger zeigen löscht.
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

So, das liegt nicht an dem Destruktor in NamedList, dondern an einem Zugriffsfehler in IniFile::vWrite(). Hättest du mit ein paar Zeilen qDebug() rausfinden können :).
Also wühl dich da mal durch, ob du mit dem iterator wirklich alles richtig machst.

Grüße
Franz

// edit
sry, bin noch nicht fit :D liegt schon am destruktor, so wie es upsala auch richtig erkannt hat :)
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

So, jetz hammas :)
Du übergibts beim Schreiben des inifile (operator<<) eine Kopie deines IniFiles. Damit hast du in der Kopie auch eine Kopie des listSections - Samt unveränderter Pointer auf die Sections! Bist du fertig mit streamen (return stream) wird die Kopie zerstört. Der Destruktor greift voll durch und deleted dir alle Sections - auch im Original! Wenn dann main fertig ist will der das Original löschen - und segfaulted.

Eine Lösung wäre z.B. eine Refernez an den Operator zu übergeben:

Code: Alles auswählen

QTextStream& operator<<(QTextStream& stream, const IniFile& file)
Klappt bei mir bestens :)
Thorsten
Beiträge: 55
Registriert: 29. Dezember 2004 22:47
Wohnort: Aachen

Beitrag von Thorsten »

Vielen Dank für eure Mühe. Ich hätte sicher viel viel länger gebraucht um den Fehler zu finden. Sie sauberste Lösung wäre wohl die Implementierung eines Copy-Konstruktors. Wenn ich diesen schon von vorne herein private gemacht hätte wären mir die Probleme wohl schon eher aufgefallen. Die Funktion qDeleteAll nutze ich jetzt auch, wobei ich es etwas blöd finde, dass diese nicht fragt, ob der betreffende Zeiger auf Null zeigt.

Nochmals vielen Dank, ihr seid echt super.

Gruß
Thorsten
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Thorsten hat geschrieben:wobei ich es etwas blöd finde, dass diese nicht fragt, ob der betreffende Zeiger auf Null zeigt.
Ich würde sagen wir lesen nochmal ein C++ - Buch :)
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Thorsten
Beiträge: 55
Registriert: 29. Dezember 2004 22:47
Wohnort: Aachen

Beitrag von Thorsten »

Ich finde, du solltest mit solchen Bemerkungen etwas vorsichtiger sein. Ich lese gerade "Modernes C++ Design, Generische Programmierung und Entwurfsmuster angewendet" von Alexandrescu, Kapitel 5: "Generalisierte Funktionen". Natürlich kann jeder noch was lernen, doch welches C++-Buch schlägst du den vor, welches "wir" lesen sollten?

Vielleicht hast du mich auch einfach nicht verstanden. Ich bin mir sicher das ich C++-Grundlagen, wie sie hier Verwendung finden, durchaus verstanden habe.

Aber zurück zu meiner Anmerkung. Was würde denn gegen einen Test auf Null sprechen. So würden Null-Zeiger im Container keinen Laufzeitfehler erzeugen. Im Debug-Modus wäre das sehr hilfreich.

Gruß
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Thorsten hat geschrieben: Aber zurück zu meiner Anmerkung. Was würde denn gegen einen Test auf Null sprechen. So würden Null-Zeiger im Container keinen Laufzeitfehler erzeugen. Im Debug-Modus wäre das sehr hilfreich.
Das ist ja gerade das was ich meine! "delete 0" gibt keinen Laufzeitfehler!
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Thorsten
Beiträge: 55
Registriert: 29. Dezember 2004 22:47
Wohnort: Aachen

Beitrag von Thorsten »

Stimmt :shock:, ich habe es gerade ausprobiert.
Wie kann man nur so lange in diesem Irrglauben leben. :oops:
Vielen Dank, dass du mich in die Wirklichkeit zurückgeholt hast. :wink:

Gruß
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Für C++ gibt es normalerweise nur ein Buch: Die Bibel: 'Die C++ Programmiersprache von Bjarne Stroustrup'
Thorsten
Beiträge: 55
Registriert: 29. Dezember 2004 22:47
Wohnort: Aachen

Beitrag von Thorsten »

Steht bei mir im Regal gleich neben Scott Meyers und gelesen habe ich es auch. Meine Frage war auch nicht wirklich ernst gemeint. Sind zwar fantastische, vielleicht auch die besten Bücher überhaupt, doch für den Anfänger völlig ungeeignet. Empfehle da Helmut Erlenkötter. Für den Einstieg sehr gut geeignet und auch preislich sehr attraktiv.

Gruß
Antworten