Deinitialisierung von TList
-
Versuch's doch mal mit einer while-Schleife, sonst werden nicht alle Elemente
der Liste gelöscht.//Das Löschen TDBListElem *DB = NULL; while (DBList->Count > 0) { DB = (TDBListElem *) DBList->Items[0]; DBList->Delete(0); delete DB; } DBList->Clear(); // Kann man sich dann eigentlich sparen delete DBList;
Gruß,
Alexander
[edit]Reihenfolge von DBList->Delete(0) und delete DB vertauscht.[/edit]
-
Also wenn ich das richtig sehe, dann ist das das Gleiche was ich auch mache nur kompakter und schöner. Aber gut ich versuch's.
-
Nein, wieder kein Erfolg. Also so langsam regt mich das Ganze ein bisschen auf.
-
Welches Objekt wird denn von CodeGuard angemeckert? Das TList-Objekt oder ein
anderes?
-
Maffe001:
Bevor du noch einen Herzinfarkt bekommst hol lieber eine zweite Meinung ein, d.h. lass deine Code mal von einem alternativen Tool wie z.B. MemProof begutachten.
CodeGuard ist schliesslich auch nur ein Mensch ...
-
@Alexander:
TDBListElem wird angemeckert.@Jansen:
Meinst du das hilft? Das Ding ist, dass CodeGuard bei allen TLists meckert, die ich zur Laufzeit erstelle und als Klassenbestandteile bis Programmende aufrecht erhalte.
Aber gut, Versuch macht kluch.
-
@Jansen:
So wie ich das hier sehe, ist MemProof nur bis BCB 5 einsetzbar. Ich schreib leider auf BCB 6.
-
Smitty schrieb:
guckst du hier:
TList tl = new TList();
.
.
.
tl.Clear();Clear löscht alle Elemente aus der Liste.
virtual void __fastcall Clear(void);
Beschreibung
Mit Clear wird das Array Items geleert, und Count sowie Capacity werden auf 0 gesetzt. Außerdem wird der gesamte vom Array belegte Speicher freigegeben.
der Satz Außerdem wird der gesamte vom Array belegte Speicher freigegeben. bezieht sich auf das Array. Nicht auf den Inhalt des Arrays.
du wirst vor Clear() die Liste durchgehen müssen :
for(int i=List->Count-1;i<0;--i) { delete (ItemType) List->Items[i]; }
-
@AndreasW:
Wenn du mal ein paar Beiträge weiter vorn schaust, dann siehst du, dass ich das schon gemacht habe.Trotzdem bleibt die Meldung die Gleiche.
-
Auf die Gefahr hin, dass ich mich wiederhole:
Siehe auf meiner Seite unter "BCB->dynamische Arrays", ganz unten.
-
@F98:
Ist ja schön und gut. Aber ich muss ehrlich sein. Wirklich verstehen tu ich das nicht. Ich hab mich noch nicht mit Templates auseinandergesetzt.
Gibt es da nicht noch einen "einfacheren" Weg?
-
Ist doch ganz einfach:
1. eine leere Unit anlegen, Template Quellcode reincopieren
2. die Template *.h in die .cpp/.h includieren, wo die TListe verwendet werden soll
3. Anwendungsbeispiele unter dem Punkt "Anwendung im Quellcode" betrachtenSo ein Template-Klasse ist auch nichts anderes als eine "normale" Klasse, mit dem Unterschied, das man verschiedene Datentypen mit einer Klasse verwalten kann.
Das Objekt, was mit der Liste verwaltet werden soll, kommt in Spitze Klammern:TListe<TBaustein> *BausteinListe; BausteinListe = new TListe<TBaustein>;
oder
TListe<TBeliebigerDatenTyp> *ListeMitBeliebigemDatentyp; ListeMitBeliebigemDatentyp = new TListe<TBeliebigerDatenTyp>;
alles weitere siehe Beispiele.
-
@F98:
So ich hab mir deine Deklaration von dem Template nochmal angeschaut.
Allerdings hab ich da gesehen, dass du im Endeffekt genau das Gleiche machst, wie ich's schon vorher (ein paar Beiträge vorher) versucht habe.
//Das Löschen
TDBListElem *DB = NULL;while (DBList->Count > 0)
{
DB = (TDBListElemDBList->Items[0];
DBList->Delete(0);
delete DB;
}
DBList->Clear(); // Kann man sich dann eigentlich sparen
delete DBList;N anderes Gutes hat dein Code aber. Ich hab ein bisschen eine Idee
davon, wie ein Template funktioniert. (Wäre vielleicht nicht schlecht, wenn du's ein bisschen sauberer darstellen würdest. ;))
Allerdings hilft mir das jetzt nicht bei meinem Problem weiter.
-
Maffe001 schrieb:
TDBListElem wird angemeckert.
Das Ding ist, dass CodeGuard bei allen TLists meckert...Was denn nun?
Meckert CodeGuard bei den TList-Objekten oder den TDBListElem-Objekten?
Bekommst Du eigentlich irgendwo beim delete Exceptions?
Hast Du schon mal versucht bei einem delete DBListElem reinzudebuggen?
Geht er da auch in den Destruktor?
Hast Du überhaupt einen Destruktor für DBListElem?Gruß,
Alexander
-
Da hab ich mich, wohl etwas missverständlich ausgedrückt.
Die Sache ist die, dass er alle TLists angemeckert hat, weil ich bei keiner die Deinitialisierung gemacht habe, wie wir vorhin. "Folglich meckert er natürlich alle TLists an." Klar ist, dass er dann die Elemente in den TLists meint.Zu TDBListElem: Wie ich schon sagte, ist TDBListElem eine Struktur. An die Liste übergebe ich ja einen Zeiger, der auf einen reservierten Speicherplatz in Form von TDBListElem zeigt. D.h. es gibt dann auch einen Destruktor für diese Elemente, nämlich delete. Oder liege ich da jetzt total falsch?
Ach ja, delete wird natürlich ausgeführt.
-
Maffe001 schrieb:
"Folglich meckert er natürlich alle TLists an." Klar ist, dass er dann die Elemente in den TLists meint.
Das ist mir nicht klar. TList verwaltet nur void*-Zeiger. Ob Du die Objekte, auf die
diese Zeiger verweisen per delete gelöscht hast, weiß CodeGuard gar nicht - die TList
übrigens auch nicht. Du kannst das ausprobieren, indem Du mal ein delete auf einen
dieser Zeiger machst und anschließend versuchst darauf zuzugreifen. Obwohl der Ver-
weis noch in der Liste ist, ist er nicht mehr gültig.
Was ich damit sagen will: Im Prinzip verwaltet TList eine Liste von long(?)-Werten,
die "zufällig" Zeiger auf Objekte sind.
Wenn CodeGuard ein nicht freigegebenes TList-Objekt anmeckert, dann meint er das auch.Maffe001 schrieb:
D.h. es gibt dann auch einen Destruktor für diese Elemente, nämlich delete. Oder liege ich da jetzt total falsch?
Ich würde sagen, ja, da liegst Du total falsch. Der Befehl delete ruft nur den De-
struktor auf. Dieser muß in Deiner Klasse deklariert und definiert sein.Gruß,
Alexander
-
Gut, wenn das so ist, dann muss es ja einen Weg geben, wie man den Speicher von Strukturen wieder freigibt.
Ich hab so'n bisschen das Gefühl, du haust da jetzt ein bisschen durcheinander. Wie ich schon sagte TDBListElem ist nur ne Struktur, keine Klasse. Und DBListElem ist ein Pointer auf einen reservierten Speicherraum.typedef struct { char DBName[50]; char StrZeit[30]; char EndZeit[30]; } TDBListElem; TDBListElem *DBListElem = new TDBListElem;
Bis jetzt bin ich immer davon ausgegangen, dass man Zeiger mit delete auch wieder löschen kann.
-
So ich muss jetzt los. Ich bin erstmal bis Dienstag nicht hier. Ich hoffe, ich kann am Dienstag mit euch auch nochmal rechnen. Vielleicht hat sich das Problem dann aber auch schon erledigt.
Thx, Maffe
-
Maffe001,
Maffe001 schrieb:
Also wenn ich das richtig sehe, dann ist das das Gleiche was ich auch mache nur kompakter und schöner.
nein, Deine for-next-Variante läßt TDBListElem-Objekte im Hauptspeicher stehen. Zähle einfach mal die delete's und vergleiche diese mit der Anzahl der Elemente in Deiner Liste. Alexanders Variante sieht korrekt aus.
-
dschensky schrieb:
Deine for-next-Variante läßt TDBListElem-Objekte im Hauptspeicher stehen.
Naja, er löscht sie nicht aus der Liste. Deswegen werden wohl doch alle TDBListElem-
Objekte gelöscht, allerdings sind dann verwaiste Einträge in der Liste.
Ich glaube nach wie vor, daß das Problem nicht die einzelnen Elemente sind, denn
diese werden - nach den Aussagen von Maffe001 - nicht von CodeGuard angemeckert.Gruß,
Alexander