AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

Array korrekt freigeben

Ein Thema von woodie · begonnen am 23. Sep 2025 · letzter Beitrag vom 26. Sep 2025
Antwort Antwort
Seite 1 von 2  1 2      
QuickAndDirty

Registriert seit: 13. Jan 2004
Ort: Hamm(Westf)
2.077 Beiträge
 
Delphi 12 Athens
 
#1

AW: Array korrekt freigeben

  Alt 24. Sep 2025, 11:00
Ihr verwirrt mich!
Ich dachte immer
Delphi-Quellcode:
Setlength(AArray,0);
AArray:=nil;
sind beides das gleiche.

und von
Finalize(AArray); Habe ich noch nie gehört! Ist das auch das gleiche?
Andreas
Nobody goes there anymore. It's too crowded!

Geändert von QuickAndDirty (24. Sep 2025 um 11:04 Uhr)
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.226 Beiträge
 
Delphi 10 Seattle Enterprise
 
#2

AW: Array korrekt freigeben

  Alt 24. Sep 2025, 11:12
Finalize ist eigentlich ein allgemeingültiges "gib das hier vorab schon mal frei" für eine dynamische Variable mit ARC (also wohl alles außer TObject).

https://docwiki.embarcadero.com/Libr...ystem.Finalize

Nehme ich eigentlich immer. Bonus: Der Compiler gibt dir einen Hinweis, wenn das nicht notwendig ist, z.B. wenn du Finalize auf einem Record aufrufst, der gar keine dynamischen Variablen hat.
  Mit Zitat antworten Zitat
QuickAndDirty

Registriert seit: 13. Jan 2004
Ort: Hamm(Westf)
2.077 Beiträge
 
Delphi 12 Athens
 
#3

AW: Array korrekt freigeben

  Alt 24. Sep 2025, 12:07
Aber dafür produziert finalize Fehler wie ein double free?
Andreas
Nobody goes there anymore. It's too crowded!
  Mit Zitat antworten Zitat
Der schöne Günther

Registriert seit: 6. Mär 2013
6.226 Beiträge
 
Delphi 10 Seattle Enterprise
 
#4

AW: Array korrekt freigeben

  Alt 24. Sep 2025, 12:23
Das bezieht sich auf die Variablen, nicht auf das Objekt dahinter. Wenn du eine Interface-Variable auf nil setzt (oder Finalize(..) aufrufst oder was immer) verringerst du den Referenzzähler. Und erst wenn der auf null geht, wird das Objekt freigegeben.

Das gleiche bei Arrays, Strings, usw.

Beispiel:

Delphi-Quellcode:
program Project5;

{$APPTYPE CONSOLE}
{$R *.res}

uses System.SysUtils;

var a, b: IInterface;

begin
   a := TInterfacedObject.Create();
   b := a;
   WriteLn( TInterfacedObject(b).RefCount ); // 2

   Finalize(a);

   Assert( not Assigned(a) );
   Assert( Assigned(b) );
   WriteLn( TInterfacedObject(b).RefCount ); // 1

   Assert( Supports(b, IInterface, {out} a) );
   Assert( Assigned(a) );
   WriteLn( TInterfacedObject(b).RefCount ); // 2
end.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.780 Beiträge
 
Delphi 12 Athens
 
#5

AW: Array korrekt freigeben

  Alt 24. Sep 2025, 12:37
sind beides das gleiche.
Im Ergebnis ist es gleich.

:=nil ist einfacher und schnell/optimaler, da hier nur freigegeben wird, während SetLength erst noch bissl prüft und dann was macht und auch anderes machen könnte (z.B. wenn nicht 0 reingegeben)

Finalize wird praktisch automatisch im END; gemacht und man verwendet es, z.B. wenn man mit Pointer rumpfuscht.

Beim Finalize (InitializeArray/FinalizeArray und InitializeRecord/FinalizeRecord, was ein Array mit Länge 1 darstellt) muß man auch teilweise aufpassen,
denn je nach Aufruf kann man sich damit alles zerballern ... z.B. mit den Finalize-Funktionen, welche am Ende nicht den Speicher Nullen
und initialize prüft nicht, ob schon was drin ist (es geht blind davon aus, dass der Speicher neu ist, also noch nie initialisiert oder gar benutzt wurde)
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (24. Sep 2025 um 12:42 Uhr)
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.836 Beiträge
 
Delphi 12 Athens
 
#6

AW: Array korrekt freigeben

  Alt 24. Sep 2025, 13:34
:=nil ist einfacher und schnell/optimaler, da hier nur freigegeben wird, während SetLength erst noch bissl prüft und dann was macht und auch anderes machen könnte (z.B. wenn nicht 0 reingegeben)
Fakten-Checker gefällig?

Dieser Code
Delphi-Quellcode:
  
  SetLength(lFilterArray, 0);
  lFilterArray := nil;
wird zu diesem Binary

Delphi-Quellcode:
Project1159.dpr.44: SetLength(lFilterArray, 0);
00D4EBDA 8D45FC lea eax,[ebp-$04]
00D4EBDD 8B152CDED300 mov edx,[$00d3de2c]
00D4EBE3 E8A4B5FEFF call $00d3a18c
Project1159.dpr.45: lFilterArray := nil;
00D4EBE8 8D45FC lea eax,[ebp-$04]
00D4EBEB 8B152CDED300 mov edx,[$00d3de2c]
00D4EBF1 E896B5FEFF call $00d3a18c
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
1.525 Beiträge
 
Delphi 11 Alexandria
 
#7

AW: Array korrekt freigeben

  Alt 24. Sep 2025, 14:01
Könnte man hier nicht auch lFilterArray := []; verwenden? Finde ich irgendwie schöner.
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.780 Beiträge
 
Delphi 12 Athens
 
#8

AW: Array korrekt freigeben

  Alt 24. Sep 2025, 20:58
Könnte man hier nicht auch lFilterArray := []; verwenden? Finde ich irgendwie schöner.
Das geht jetzt/inzwischen.
Früher ging es ja nicht, dass man dynamische Arrays so zuweisen konnte.

Wäre wohl angebracht nachzusehn, ob die CodeOptimierung auch hier funktioniert.
Beim SetLength war es mal so, dass es nicht / nicht immer optimiert wurde und dann wirklich der Aufruf auf System._DynArraySetLength erfolgte.

[edit]
Jupp, sieht gut aus. (ist wohl direkt passende CompilerMagic ... nicht erst die CodeOptimierung, denn im Debug-Profil ist die ja aus)
Delphi-Quellcode:
Unit3.pas.29: SetLength(TestArray, 3);
008042B3 6A03 push $03
008042B5 8D45F8 lea eax,[ebp-$08]
008042B8 B901000000 mov ecx,$00000001
008042BD 8B1568428000 mov edx,[$00804268]
008042C3 E8008FE2FF call $0062d1c8 // System._DynArraySetLength
008042C8 83C404 add esp,$04

Unit3.pas.30: TestArray := [];
008042CB 8D45F8 lea eax,[ebp-$08]
008042CE 8B1568428000 mov edx,[$00804268]
008042D4 E81390E2FF call $0062d2ec // System._DynArrayClear

Unit3.pas.31: SetLength(TestArray, 0);
008042D9 8D45F8 lea eax,[ebp-$08]
008042DC 8B1568428000 mov edx,[$00804268]
008042E2 E80590E2FF call $0062d2ec // System._DynArrayClear

Unit3.pas.32: TestArray := nil;
008042E7 8D45F8 lea eax,[ebp-$08]
008042EA 8B1568428000 mov edx,[$00804268]
008042F0 E8F78FE2FF call $0062d2ec // System._DynArrayClear
Ein Therapeut entspricht 1024 Gigapeut.

Geändert von himitsu (24. Sep 2025 um 21:06 Uhr)
  Mit Zitat antworten Zitat
QuickAndDirty

Registriert seit: 13. Jan 2004
Ort: Hamm(Westf)
2.077 Beiträge
 
Delphi 12 Athens
 
#9

AW: Array korrekt freigeben

  Alt 24. Sep 2025, 14:33
Delphi-Quellcode:
Project1159.dpr.44: SetLength(lFilterArray, 0);
00D4EBDA 8D45FC lea eax,[ebp-$04]
00D4EBDD 8B152CDED300 mov edx,[$00d3de2c]
00D4EBE3 E8A4B5FEFF call $00d3a18c
Project1159.dpr.45: lFilterArray := nil;
00D4EBE8 8D45FC lea eax,[ebp-$04]
00D4EBEB 8B152CDED300 mov edx,[$00d3de2c]
00D4EBF1 E896B5FEFF call $00d3a18c
Also ist es doch an sich das selbe? nur finalize ist anders aber ich verstehe nicht ganz warum ich es brauche.
In welcher situation fuktioniert ":= nil" nicht und finalize muss benutzt werden? Speziell für Arrays und Records.
Andreas
Nobody goes there anymore. It's too crowded!
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
11.836 Beiträge
 
Delphi 12 Athens
 
#10

AW: Array korrekt freigeben

  Alt 24. Sep 2025, 15:43
Hier ist das ausführlich erklärt - man muss es aber auch ganz lesen: System.Finalize

Wichtig ist dabei folgende Sequenz:
Zitat:
Wenn auf eine dynamische Variable folgende Bedingungen zutreffen, ist ein Aufruf von Finalize erforderlich, um die Variable vor ihrer Deallozierung zu finalisieren.

Die Variable wird nicht mit der Standardprozedur Dispose (sondern z.B. mit FreeMem) freigegeben.

Die Variable enthält lange Strings, Varianten und Interfaces, die nicht alle leer sind bzw. den Wert Unassigned haben.
Es müssen beide Bedingungen zutreffen, also insbesondere die dynamische Erzeugung/Freigabe und dann auch nur wenn dabei kein New/Dispose verwendet wird.

Im konkreten Fall sind alle deklarierten Array-Variablen, die über SetLength oder ein Copy ihren Speicher bekommen, nicht davon betroffen, da der Compiler weiß was damit zu tun ist und den nötigen Aufräumcode entsprechend anlegt.

Ich kann mich nicht erinnern, wann ich das letzte Mal wirklich ein Finalize schreiben musste.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:06 Uhr.
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz