Delphi-PRAXiS
Seite 1 von 3  1 23      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi Was macht Free genau in einem Array (https://www.delphipraxis.net/58531-macht-free-genau-einem-array.html)

s.h.a.r.k 8. Dez 2005 15:40


Was macht Free genau in einem Array
 
Abend :wink:

Hab da grad ein Problem - denke wohl eher ein Verständnis-Problem: Und zwar habe ich ein variables Array, das von einem eigenen Typ ist, nehmen wir mal an von Typ TFont. Nun habe ich eine Procedure Add, mit der ich dem Array von mir aus 10 Einträge hinzufüge. Danach will ich den letzten Eintrag löschen und habe bisher das so gemacht:

Delphi-Quellcode:
MyArray[9].Free;
setlength(MyArray, length(MyArray) - 1);
Mein Gedanke: Mit Free gebe ich den belegten Speicher wieder frei und mit dem setlength verkürze ich das Array. Allerdings bringt mir Delphi bei einer späteren Verwendung des Array ein EA-Fehler, was ich irgendwie nicht ganz versteh: Den das Free gibt auch irgendwie das Array-Feld frei - nur warum?!?! Stimmt meine letzte Annahme überhaupt???

mfg shark

ichbins 8. Dez 2005 16:00

Re: Was macht Free genau in einem Array
 
:gruebel:

Das free gibt nur die Font-Variable frei, die in dem Speicherbereich gespeichert ist. Bei mir läuft alles Glatt:

Delphi-Quellcode:
var
  a:array of tfont;
  i:integer;
begin
  setlength(a,10);
  for i:=0 to length(a)-1 do
    a[i]:=tfont.create;
  a[length(a)-1].Free;
  setlength(a,length(a)-1);
  a[5].Size:=10;
  a[8].Name:='Hallo';
end;
Es kommt keine Exception.

Könnte es vllt sein dass du nochmal auf Element [9] zugreifst?

Der_Unwissende 8. Dez 2005 16:01

Re: Was macht Free genau in einem Array
 
Zitat:

Zitat von s.h.a.r.k
Mein Gedanke: Mit Free gebe ich den belegten Speicher wieder frei und mit dem setlength verkürze ich das Array. Allerdings bringt mir Delphi bei einer späteren Verwendung des Array ein EA-Fehler, was ich irgendwie nicht ganz versteh: Den das Free gibt auch irgendwie das Array-Feld frei - nur warum?!?! Stimmt meine letzte Annahme überhaupt???

Hi,
also mit dem Free gibst du definitiv nicht das komplette Array frei, sondern machst genau das was du möchtest (vorrausgesetzt ich hab dich richtig verstanden). Wenn du ein TFont aFont anlegst und an der Stelle 10 ins Array schreibst, dann wird eben aFont freigegeben.
Wird die Referenz noch irgendwo im Programm benutzt, so ist diese natürlich genauso freigegeben worden. Wenn du also nach einem solchen Free ein Problem hast, solltest du nochmal kontrollieren, ob du noch irgendwo anders auf das gleiche Element verweist und natürlich auch, dass du nicht über die Grenzen des Arrays hinaus gehst (nach Verminderung).

Gruß Der Unwissende

s.h.a.r.k 8. Dez 2005 16:08

Re: Was macht Free genau in einem Array
 
Vielleicht habe ich mich etwas kompliziert ausgedrückt: Und zwar wie schon gesagt habe ich ein Array der Länge 10 und lösche nun z.B. das Fünfte über eine Procedure Delete, die wie folgt aussieht:

Delphi-Quellcode:
procedure TMyClass.Delete(Index: Integer);
var
  i : Integer;
begin
  MyArray[Index].Free;
  for i := Index to length(MyArray) - 2 do MyArray[i] := MyArray[i + 1];
  setlength(MyArray, length(MyArray) - 1);
end;
Nun ist es allerdings so, dass das Free schon eine Dekrementierung des Arrays bewirkt, was ich allerdings nicht wirklich verstehe...

PS: Sicherheitsabfragen bei der Procedure habe ich weggelassen.

Ratte 8. Dez 2005 16:43

Re: Was macht Free genau in einem Array
 
Es könnte sein, dass die Zuweisung an die leere Speicherstelle nicht klappt. Lass mal das .free weg oder bau in die Schleife noch ein .free ein (jeweils für MyArray[i] bevor du das darrauffolgende zuweist.

Ratte

Flocke 8. Dez 2005 16:53

Re: Was macht Free genau in einem Array
 
Zitat:

Zitat von s.h.a.r.k
Nun ist es allerdings so, dass das Free schon eine Dekrementierung des Arrays bewirkt, was ich allerdings nicht wirklich verstehe...

Das wäre nur dann der Fall, wenn deine Klasse so `schlau´ wäre, sich im Destruktor selbst aus der Liste zu löschen.

// Nachtrag:

Zitat:

Zitat von Ratte
Lass mal das .free weg oder bau in die Schleife noch ein .free ein (jeweils für MyArray[i] bevor du das darrauffolgende zuweist.

Das ist Unsinn, weil er MyArray[i] ja vorher an MyArray[i - 1] zugewiesen hat.

QuickAndDirty 8. Dez 2005 17:00

Re: Was macht Free genau in einem Array
 
Könnte es sein das dieser fehler nur dann passiert wenn du das letzte verbleibende element aus dem array löschst?
Das DynArray wird nämlich über ein Interface auf @$00000000 gesetzt wenn alle element entfernt wurden.
sprich es wird freigegeben wenn der Referenzzähler 0 erreicht.

Ratte 8. Dez 2005 17:04

Re: Was macht Free genau in einem Array
 
@Flocke: stimmt natürlich. Sorry für's Unsinn verbreiten...

Ratte

s.h.a.r.k 9. Dez 2005 08:29

Re: Was macht Free genau in einem Array
 
Zitat:

Zitat von QuickAndDirty
Könnte es sein das dieser fehler nur dann passiert wenn du das letzte verbleibende element aus dem array löschst?
Das DynArray wird nämlich über ein Interface auf @$00000000 gesetzt wenn alle element entfernt wurden.
sprich es wird freigegeben wenn der Referenzzähler 0 erreicht.

Hm... nein, eben das nicht. Wenn ich das letzte lösche tritt da nie der Fehler auf, was ich allerdings etwas seltsam finde... daher verstehe ich auch nicht ganz warum es nicht klappen will. :gruebel:


PS: Kann es eventuell an meiner eigenen Destroy-Procedure liegen?! Die schaut nämlich wie folgt aus:
Delphi-Quellcode:
procedure TMyClass.Destroy;
begin
  // FSub -> Unterklasse von TMyClass
  FSub.Free;
  // FTest -> Variable von Typ TMyClass
  FTest.Free;
  inherited Destroy;
end;

Pseudemys Nelsoni 9. Dez 2005 08:59

Re: Was macht Free genau in einem Array
 
Zitat:

Zitat von s.h.a.r.k
Vielleicht habe ich mich etwas kompliziert ausgedrückt: Und zwar wie schon gesagt habe ich ein Array der Länge 10 und lösche nun z.B. das Fünfte über eine Procedure Delete, die wie folgt aussieht:

Delphi-Quellcode:
procedure TMyClass.Delete(Index: Integer);
var
  i : Integer;
begin
  MyArray[Index].Free;
  for i := Index to length(MyArray) - 2 do MyArray[i] := MyArray[i + 1];
  setlength(MyArray, length(MyArray) - 1);
end;
Nun ist es allerdings so, dass das Free schon eine Dekrementierung des Arrays bewirkt, was ich allerdings nicht wirklich verstehe...

PS: Sicherheitsabfragen bei der Procedure habe ich weggelassen.

Beim löschen eines Feldes Deines Arrays solltest du die schleife auf jeden Fall rückwärts(downto) laufen lassen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 22:47 Uhr.
Seite 1 von 3  1 23      

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