Deinitialisierung von TList
-
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
-
Alexander Kempf schrieb:
...werden wohl doch alle TDBListElem-
Objekte gelöscht*aaargh*, hab mich verguckt (Kartoffeln auf den Augen).
@Maffe001: Ich nehme alles zurück.
-
So da bin ich wieder. Ich hab mir die ganze Geschichte nochmal angeschaut, bin aber leider nicht weitergekommen. Nochmal zur Zusammenfassung. Der Codeguard gibt nach wie vor folgendes zurück:
The object (0x....) was never deleted
.
.
The object (0x....)(size: 1028 bytes) was created with new
TDBHandle::DBs_to_List (char
.
.Wenn ich auf *TDBHandle::DBs_to_List (char ) doppelklicke, dann komme ich bei dem Eintrag DB = new TDBListElem raus.
Wie schon gesagt, wenn DB mit Werten gefüllt ist, dann wird er in eine TList mit Add eingetragen.
Zum Löschen der TList und der Elemente benutze ich folgende Methode:
while (DBList->Count > 0) { TDBListElem *DB = (TDBListElem *) DBList->Items [0]; DBList->Delete (0); delete DB; } delete DBList;
Tut mir leid, ich schein da einiges letzte Woche durcheinander gehauen zu haben.
-
Maffe001 schrieb:
Wenn ich auf *TDBHandle::DBs_to_List (char ) doppelklicke, dann komme ich bei dem Eintrag DB = new TDBListElem raus.
Zeig doch mal, was Du an der Stelle machst (Quellcode).
Hast Du schon mal überprüft, ob Du vielleicht irgendwelche TDBListElem-Objekte
erzeugst, die Du dann aber nicht der Liste hinzufügst?Gruß,
Alexander
-
Also grob gesagt, erzeuge ich mehrere Datenstrukturen, die Datenbanken widerspiegeln sollen, die ich über ein Request an MySql auslese. Die Stelle sieht so aus.
MYSQL_RES *Res = mysql_store_result (hDB); int NumZ = (int) mysql_num_rows (Res); if (NumZ != 0) { TList *DBList = new TList; MYSQL_ROW Zeile; int NumFlds = 0; TDBListElem *DB = NULL; NumFlds = mysql_num_fields (Res); while (Zeile = mysql_fetch_row (Res)) { DB = new TDBListElem; for (int zaehler1 = 0; zaehler1 < NumFlds; zaehler1++) { switch (zaehler1) { case 0: sprintf (DB->DBName, Zeile[zaehler1]); break; case 1: sprintf (DB->StrZeit, Zeile[zaehler1]); break; case 2: sprintf (DB->EndZeit, Zeile[zaehler1]); break; } } DBList->Add (DB); DB = NULL; delete DB; //ja, ich weiss die Stelle ist Quatsch. // ist mir auch gerade aufgefallen. } mysql_free_result (Res); } . . .
Du siehst also, dass keine Elemente übrig bleiben, die nicht eingefügt werden. Oder doch.
-
Ist das eine Methode? Falls ja, dann verstehe ich die Deklaration von DBList
innerhalb der Methode nicht so ganz.TList *DBList = new TList;
Allerdings würde ich dann verstehen, weshalb CodeGuard meckert.
Wenn das eine Methode ist und Du diese mehr als einmal aufrufst, könnte ich
ebenfalls verstehen, daß CodeGuard meckert - oder wird am Ende dieser Methode
alles gelöscht? Dann würde ich den Sinn für die Liste nicht verstehen...
Irgendwie verstehe ich den Zusammenhang noch nicht so genau...Gruß,
Alexander
-
Die Liste wird nur einmal erzeugt. Das Füllen der Liste geschieht in der while-Schleife.
Meinst du das? Wenn ich ehrlich bin verstehe ich jetzt auch nicht so ganz, was du meinst.
-
Zeig doch mal alles von der Erzeugung bis zum Löschen. Also, wenn Du das nicht
in einer Methode machst, wo dann? Wenn ja, zeig auch mal, wo und wie Du die
Methode aufrufst.Gruß,
Alexander
-
Die Erzeugung steht doch 2 Beiträge vorher schon. Oder meinst du die Erzeugung von TList etc.? Die kann ich dir nicht geben, weil TList ja schon ein vordefiniertes Objekt ist.
Die Erzeugung von TList geschieht halt mit:
TList *DBList = new TList; //Man könnte es auch so schreiben. TList *DBList = NULL; DBList = new TList;
Erklärt das jetzt deine Frage? Oder meinst du was ganz anderes?
-
Maffe001 schrieb:
Erklärt das jetzt deine Frage?
Nein. Wie ich schon sagte, fehlt mir ein bißchen der Zusammenhang.
Du zeigst nur immer ein paar Code-Zeilen, die die Erzeugung und das Füllen
der Liste mit ihren Elementen zeigt und ein paar Zeilen, die das Löschen
zeigen. Beide für sich sehen für mich eigentlich ganz in Ordnung aus, aber
es scheint ja doch irgendwo ein Fehler drinzustecken. Deshalb würde ich gerne
sehen, an welchen Stellen Du das Erzeugen/Löschen vornimmst.
Im Moment sieht es für mich so aus, als ob Dein Programm aus einem großen
monolithischen Block besteht, innerhalb dessen einmal eine Liste erzeugt und
gefüllt wird, um gleich darauf wieder auf die Elemente zuzugreifen und danach
alles wieder wegzuwerfen. Das würde mir aber nicht sehr sinnvoll erscheinen
und wahrscheinlich hast Du das auch nicht so gemacht (hoffentlich).Also, ich verwende Listen so, daß ich eine Klassenvariable vom Typ TList habe,
die im Konstruktor per new erzeugt wird. Andere Methoden meiner Klasse fügen
dieser Liste Objekte hinzu oder löschen sie auch wieder heraus (add/remove).
Im Destruktor der Klasse passiert dann das, was Du auch machst, nämlich alle
Elemente zu löschen und die Liste selbst auch.
Wenn Du die Liste auch so verwendest, dann zeig doch mal die entsprechenden
Methoden (inklusive Signatur) und die Aufrufe dieser Methoden. Vielleicht wird
dann der Zusammenhang für mich klarer.
Alles andere ist für mich Herumgestochere im Nebel.Gruß,
Alexander
-
Maffe001:
Vielleicht solltest du das Problem mal in einem (abstrakten) Minimalprojekt nachstellen, bei dem du ggf. auch den kompletten Code zwecks Nachvollziehen an andere weitergeben kannst.
Ausserdem lässt sich so prüfen, ob es sich um ein generelles Problem z.B. mit TList handelt oder ob der Fehler vielleicht doch irgendwo anders in deinem Hauptprogramm liegt.
-
Na gut, ich umreiße mal grob mein Vorhaben. Also es ist so, dass ich eine Anwendung schreibe, die in eine MySql-Datenbank die Daten von verschiedenen Messgeräten einträgt.
Für jede neue Messung wird eine neue DB angelegt, für jedes Messgeräte eine eigene Tabelle.
Um zu kontrollieren welche Messungen auf dem Rechner überhaupt "aktuell" sind, hab ich noch eine "globale" DB angelegt, die alle DB mit Namen, Startzeit und Endzeit abspeichert. So kann ich jetzt mit einem Vergleich von den vorhandenen DBs auf dem MySql-Server und den eingetragenen DBs in der globalen DB herausfinden, welche Messungen überhaupt noch vorhanden sind.
In meiner Arbeitsgruppe wurde entschieden, dass DBs, die nur auf dem Server aber nicht in der "globen" DB vorhanden sind und anders herum, nicht als Messung angesehen werden und somit auch nicht auf der graphischen Oberfläche angezeigt werden.Die Operationen der Anwendung auf MySql hab ich in einer eigenen Klasse (TDBHandle) gekapselt, so dass man die ganze Geschichte vielleicht auch noch mal woanders benutzen kann.
Der angesprochene Vergleich wird durchgeführt, wo die Liste angelegt wird, wenn die Initialisierungsfunktion (nicht der Konstruktor von TDBHandle) ausgeführt wird. Danach werden noch verschieden Operatioen auf diese Liste ausgeführt, wobei sie sich aber nicht mehr ändert.
Die angelegte Liste ist ein Mitglied von TDBHandle und soll dann im Destruktor von TDBHandle wieder glöscht werden.Ich weiss nicht, was ich noch schreiben soll. Alles was mit der Liste zu tun hat, steht schon in den Beiträgen weiter oben.
Wie gesagt, zwischen Erstellung und Löschen der Liste, geschehen nur noch Leseoperationen darauf.
-
Ich hab's endlich doch noch geschafft. Dadurch, dass ich mal mein Vorhaben beschreiben sollte, bin ich auf die richtige Idee gekommen.
Es lag gar nicht an dieser einen Liste, sondern an allen Listen die ich für den Vergleich gebraucht habe. Da ich ja bei einem Treffer in einem Vergleich nur die Elemente aus einer List übernommen habe, die dann auch zum Ende gelöscht wurden, blieben die Elemente der anderen Liste natürlich im Speicher, weshalb CodeGuard gemeckert hat.Allerdings verstehe ich nicht, warum CodeGuard mich in dem Baum bis in eine Funktion gebracht hat, die im nicht mal im entferntesten mit den Vergleichslisten zu tun hatte, sondern eigentlich nur noch mit der Trefferliste?
(Wenn jemand da etwas besser Bescheid weiß. Es interessiert mich auf jeden Fall.)
Ansonsten Danke an alle, die mir versucht haben zu helfen.