ich habe ein Problem mit einer selbst gebastelten Klasse „iTunesClass“,
die alle Stücke aus einer iTunes-XML ausliest und eine doppelt verkettete Liste aus Stücken im Speicher erstellt.
Wenn ich im Beispielprogramm eigenhändig „delete“ auf eine geladene Bibliothek anwende, scheint es so, als würde am Ende des Programmes alles noch einmal gelöscht werden, bzw. der Destruktor wird erneut aufgerufen. Der versucht dann Sachen zu löschen, die es gar nicht mehr gibt -> Segmentation fault.
Ich habe einen Foreneintrag gefungden ( http://bytes.com/topic/c/answers/826920-segmentation… ), in dem ein fehlender Copykonstruktor als mögliche Ursache gehandelt wird, was ich nicht so ganz verstehe. Was hat der Copykonstruktor mit dem Destruktor zu tun?
Ich poste erstmal keine Codeschnippsel, da das sehr lang und unübersichtlich wäre. (kann ich aber noch nachholen, wenns nötig wird)
kurze und knappe Regel: wenn deine Klasse etwas dynamisch allokiert (new) oder einen Zeiger verwaltet, der dann final in der Klasse freigegeben wird, dann muss ein Copy Constructor und ein Assignment Operator implementiert werden.
Ansonsten kann es sein, dass ein delete in einem Destruktor etwas versehentlich mehrfach löscht, nämlich dann, wenn nur dein interner Zeiger kopiert wurde.
nächste Frage: Warum? Wofür braucht der Destruktor sowas? Kannst du das genauer erläutern?
Frage: Ich habe einfach mal deine Regel befolgt und sowohl Copykonstruktor als auch Zuweisungsoperatoren definiert. Funzt nicht. Jetzt kommen doch ein paar Schnippsel:
Das macht er wenn er ein neues Track-Objekt erstellt (Er geht die iTunes-XML schleifenweise durch):
Track::~Track()
{
if (this-\>previous != NULL)
this-\>previous-\>next = this-\>next; //Fehler an dieser Stelle (siehe unten)
if (this-\>next != NULL)
this-\>next-\>previous = this-\>previous;
if (mother != NULL)
--(mother-\>TrackCount);
}
Die Fehlerausgabe:
Program received signal SIGSEGV, Segmentation fault.
At C:/Projects/iTunesClass/iTunesClass.cpp:337
Copykonstruktor und Zuweisungsoperator füge ich hier mal nicht ein, ich glaube nicht, dass da der Fehler liegt.
nächste Frage: Warum? Wofür braucht der Destruktor sowas?
Kannst du das genauer erläutern?
Nicht der Destructor braucht das, dein Programm braucht das.
Copy Constructor und Assignment Operator sind unabhaengig vom Destructor.
Ist m_p eine Member Pointer Variable, dann kann diese - sofern du die oben genannten Sachen nicht hast- vorher einfach „by value“ mitkopiert worden sein, so dass du ein Objekt x und eine Kopie des Objekts y hast. Beide zeigen auf den nur einmal allokierten Bereich. Würde im destructor ein delete m_p stehen, so wuerdest du aber versuchen das Ganze mehr als einmal freizugeben.
Im uebrigen befindet sich in dem von dir geposteten Stueck Code kein explizites delete. Vielleicht solltest du doch ein paar mehr Codestuecke, inklusive dem Stueck, in dem sich das delete befindet, posten.
while (pointer != NULL)
{
tracktemp = new Track(*pointer);
this->AddTrack(tracktemp);
pointer = pointer->next;
}
}
Das gleiche für Track (gekürzt)
void Track::do_copy(const Track& temp)
{
Track_ID = temp.Track_ID;
Name = temp.Name;
Artist = temp.Artist;
// usw.
}
Das interessante ist, der Fehler tritt nur auf wenn ich die ca. 1400 Stücke mit diesem Konstruktor aus meiner Bibliothek lade. Wenn ich im Beispielprogramm 3 Track-Objekt erstelle und dann mit „AddTrack“ in die Bibliothek einfügen lasse, läuft es.
Beispielprogramm (der Konstruktor benutzt den Code aus dem
letzten Post)
int main(int argc, char *argv[])
{
iTunesLib Biblio(„c:\itunesganz.xml“);
delete &Biblio;
return EXIT_SUCCESS;
}
fangen wir mal mit dem Offensichtlichen an. Dein Biblio ist kein dynamisch erzeugtes Objekt. D.h. man darf es nicht mit delete löschen. Es wird automatisch gelöscht, wenn es „out-of-scope“ fällt, in diesem Fall mit Ende der ‚}‘.
ich hatte mir vorgenommen, dass mir sowas nie passiert *haare rauf*
Da sitzt man jahrelang vorm debugger und dann sowas… ich könnt mir selbst in die eier treten. Gibt’s einen Namen für solche Momente??
Naja…das muss ich erstmal verdauen.
DANKE, deine Geduld möchte ich haben
Gibs zu, du machst das doch auch nur um den Leuten hinterher beim in-die-Eier-Treten zuzugucken !
bis später…wenn du mal in der Situation bist… oder vergeht das mit der Zeit…?
Arlecks
könnt mir selbst in die eier treten. Gibt’s einen Namen für
solche Momente??
… oder vergeht das mit der Zeit…?
nein, nicht wirklich, man kann die Häufigkeit optimieren, aber ganz weg bekommt man das nicht Sprich: etwas Ähnliches passiert jedem Programmierer mit Regelmässigkeit ab und an …