Delphi-PRAXiS
Seite 3 von 4     123 4      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Clear von TList überschreiben mit Objekten (https://www.delphipraxis.net/95209-clear-von-tlist-ueberschreiben-mit-objekten.html)

Luckie 3. Jul 2007 12:08

Re: Clear von TList überschreiben mit Objekten
 
Auch wenn ich Nach TImageEnVect catse kommt es zur AV. Wo er genau in der Assign-Methode aussteigt versuche ich gerade zu ermitteln.

aber es ist doch richtig, dass es zu einem Speicherleck an dieser Stelle kommt, wenn ich in der Methode Clear die Objekte in der Liste nicht freigebe oder?

hoika 3. Jul 2007 12:14

Re: Clear von TList überschreiben mit Objekten
 
Ja,

ist richtig.
Ich habe den Tag rot angestrichen, als ich von memcheck gehört habe ;)
Naja, die folgenden Tage war ich mit Leck abdichten beschäftigt ;)


Heiko

Phantom1 3. Jul 2007 12:23

Re: Clear von TList überschreiben mit Objekten
 
Zitat:

Zitat von Luckie
aber es ist doch richtig, dass es zu einem Speicherleck an dieser Stelle kommt, wenn ich in der Methode Clear die Objekte in der Liste nicht freigebe oder?

Speicherlecks dürfte es eigentlich nicht geben, da ja beim TList.destroy auch die clear methode immer aufgerufen wird.

Ich empfehle aber trotzdem FInnerList.Clear in deiner TPageCollection.clear methode aufzurufen.

DGL-luke 3. Jul 2007 12:24

Re: Clear von TList überschreiben mit Objekten
 
Eine TList macht glaube ich nur ein Dispose beim Clear. Das heißt, hat man Objekte drin, dann gibts n Speicherleck, wenn man die nicht zuvor freigibt.

Luckie 3. Jul 2007 12:26

Re: Clear von TList überschreiben mit Objekten
 
Ich habe mal nachgeguckt. Clear von TList setzt nur die Länge und Kapazität auf null. Da wird also nichts freigegeben.

Phantom1 3. Jul 2007 12:27

Re: Clear von TList überschreiben mit Objekten
 
Zitat:

Zitat von DGL-luke
Eine TList macht glaube ich nur ein Dispose beim Clear. Das heißt, hat man Objekte drin, dann gibts n Speicherleck, wenn man die nicht zuvor freigibt.

Ja, aber Luckie gibt ja die Objekte direkt frei, von daher gibt es keine speicherlecks:
Delphi-Quellcode:
procedure TPageCollection.Clear;
var
  i: Integer;
begin
  for i := FInnerList.Count - 1 downto 0 do
  begin
    TObject(FInnerList.Items[i]).Free;
  end;
  FInnerList.Clear;
end;

Luckie 3. Jul 2007 12:31

Re: Clear von TList überschreiben mit Objekten
 
Nur leider führt dieser Code zu einer AV, wenn ich danach Assign aufrufe.

Hawkeye219 3. Jul 2007 12:34

Re: Clear von TList überschreiben mit Objekten
 
Hallo Michael,

ein Leck könnte hier entstehen:

Delphi-Quellcode:
procedure TPageCollection.SetItem(Index: Integer; Item: TImageEnVect);
begin
  FInnerList.Items[Index] := Item;
end;
TList schickt zwar beim Entfernen des alten Elements eine Notification, aber erst in TObjectList wird diese Nachricht abgehört. Du solltest also vor der Zuweisung das alte Element selbst freigeben.

Was die AV angeht: wurden die TImageEnVect-Controls eventuell schon von ihrem Parent zerstört, wenn du versuchst, sie zu freizugeben? klick

Gruß Hawkeye

Luckie 3. Jul 2007 13:02

Re: Clear von TList überschreiben mit Objekten
 
Ich sehe gerade im Debugger:
Zitat:

Debug Output: FastMM has detected an attempt to call a virtual method on a freed object. An access violation will now be raised in order to abort the current operation.

Freed object class: TImageEnVect

Virtual method: Destroy

Virtual method address: 5BC0D0

Process DWFotoBook.exe (3288)
Heißt dass, dass da schon was freigegeben wurde? Ich wüsste aber nicht wo das im Quelltext passiert sein sollte.

Phantom1 3. Jul 2007 13:27

Re: Clear von TList überschreiben mit Objekten
 
Ich denke mal du gibts irgendwo vorher schon ein TImageEnVect-objekt mit FInnerlist.Items[i].free, aber vergisst diesen itemeintrag auch aus der TList zu löschen mit FInnerlist.delete(i).

bsp:

du hast 4 objekte in der TList:

Finnerlist.Items[0]
Finnerlist.Items[1]
Finnerlist.Items[2]
Finnerlist.Items[3]

und du gibst jetzt das 3te Item frei mit FInnerlist.Items[2].free (ohne anschließenden aufruf finnerlist.delete(2)), dann sieht es so aus;

Finnerlist.Items[0]
Finnerlist.Items[1]
Finnerlist.Items[2] (item immernoch verhanden, aber objekt bereits freigegeben
Finnerlist.Items[3]

In deiner Assign methode werden dann alle objekte durchgegangen und auf FInnerlist.Items[2] zugegriffen, obwohl das objekt bereits freigegeben wurde.


Alle Zeitangaben in WEZ +1. Es ist jetzt 12:48 Uhr.
Seite 3 von 4     123 4      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz