Verkettete Liste - Entfernen von Elementen
-
p.S.: nochwas: wenn du macros hast die wie Funktionen aufzurufen sind ist es gut wenn du die so schreibst:
#define foo(p) do { delete p; p = 0; } while(0)Dann funktionieren nämlich u.A. solche Konstrukte wie erwartet:
#define foo(p) do { delete p; p = 0; } while(0) void bar(int* p) { if (blubb()) foo(p); }
-
Ach das meinte er... die Mitglieder werden alle auf 0 initialisiert. Das ist bei mir fix drin :D. Wie man sieht hab ich den Konstruktor mit [...] ja auch weggekürzt. Also keine Panik :).
Aber ob classptr(NULL) oder classptr = NULL sollte doch egal sein oder?
Weil der Compiler spuckt ja keine ne Warnung aus. Und der MSVC-Compiler is eigentlich recht pingelig.#define dtDelete(ptr) delete ptr; ptr = NULL; // das if braucht man nicht, delete ist OK mit null pointernDAS wusste ich nicht... danke.
rya.
-
Scorcher24 schrieb:
Aber ob classptr(NULL) oder classptr = NULL sollte doch egal sein oder?
Weil der Compiler spuckt ja keine ne Warnung aus. Und der MSVC-Compiler is eigentlich recht pingelig.Für so triviale Objekte wie Zeiger ist es egal, ob du sie per Initialisierungsliste oder im Ctor-Rumpf auffüllst. Aber bei "größeren" Objekten macht es schon einen Unterschied (in der Laufzeit), ob sie erst default-initialisiert und anschließend überschrieben oder gleich mit dem endgültigen Wert gefüllt werden.
(und dann gibt es noch Referenzen, const-Member und Klassen ohne Default-Ctor - die nur über die Initialisierungsliste vorbelegt werden können)btw, im Dtor ist es doch egal, wohin dein Zeiger hinterher zeigt - im nächsten Arbeitsschritt wird der sowieso pulverisiert
(sprich: anstelle deines Makros reicht ein einfaches delete m_data;aus). Und anstelle des Zeigers würde ich lieber den Wert im Listenelement speichern.
-
hustbaer schrieb:
p.S.: nochwas: wenn du macros hast die wie Funktionen aufzurufen sind ist es gut wenn du die so schreibst:
#define foo(p) do { delete p; p = 0; } while(0)Dann funktionieren nämlich u.A. solche Konstrukte wie erwartet:
#define foo(p) do { delete p; p = 0; } while(0) void bar(int* p) { if (blubb()) foo(p); }Interessanter Tipp !!
Würde es nicht reichen, einen eigenen Scope aufzumachen (ohne das do/while) ? Mir fällt jetzt spontan kein Beispiel ein, wo es das nicht das.
Gruß,
Simon2.
-
(D)Evil schrieb:
2. Designfehler: Initialisierungsliste
Was hat das denn mit Design zu tun?
-
Nein, würde nicht reichen - versuch' doch mal sowas:
#define remove(x) {delete x;x=0;} if(bed) remove(ptr); else cout<<"Ich lebe noch";Zur Erklärung: Nach dem Präprozessor bleibt davon:
if(bed) { delete ptr;ptr=0; } ; else cout<<"Ich lebe noch";-> der Inhalt des Makros wird als Anweisung im if-Zweig eingetragen, das anschließende Semikolon ergibt eine leere Anweisung - und das else steht plötzlich alleine im Raum.
PS: In C++ würde ich gar kein Makro verwenden, sondern lieber
template<typename T> void dtDelete(T*& ptr) { delete ptr; ptr=0; }
-
Danke für die netten Tips
Aber hat jemand eine Lösung für das eigentliche Problem?
Zur Wiederholung:
Nach dem Löschen eines Elements und dem "Umbiegen" der Zeiger, zeigen diese immer noch auf das gelöschte Element... komischerweise.
rya.
-
Das sollten sie aber eigentlich nicht mehr - hast du mal im Debugger verfolgt, was tatsächlich unterwegs passiert?
-
Habs jetzt mehrfach durch den Debugger gejagt -> selbes Problem.
Hab dann mal die DLL komplett neu gebaut und den Client -> Problem verschwunden..^^
Ich schätze da war mal wieder der Wurm drin.. trotzdem danke.
rya.
-
Scorcher24 schrieb:
Habs jetzt mehrfach durch den Debugger gejagt -> selbes Problem.
Du solltest nicht nur das Ergebnis im Debugger beurteilen, sondern den Ablauf mal im Detail verfolgen (um zu sehen, wann welche Variablen den Wert verändern)
Hab dann mal die DLL komplett neu gebaut und den Client -> Problem verschwunden..^^
Ich schätze da war mal wieder der Wurm drin.. trotzdem danke.
rya.Die Liste war in einer DLL? Da könnte es auch sein, daß du mit einer veralteten Version gearbeitet hast.