Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi free erzeugt Fehler (https://www.delphipraxis.net/152887-free-erzeugt-fehler.html)

fui-tak 11. Jul 2010 14:24

free erzeugt Fehler
 
Hallo zusammen,
ich habe da ein Problem mit der free Methode:


Delphi-Quellcode:
...
levels[3] := levels[1];
...



destructor TSpielverwalter.Destroy;
var i: integer;
begin

  for i := 0 to high(levels) do
     levels[i].free;


  inherited;
end;

Wenn die Schleife jetzt bei 3 ankommt, gibt's einen Fehler, nämlich "Erste Gelegenheit für Exception bei $758EB727. Exception-Klasse EInvalidPointer mit Meldung 'Ungültige Zeigeroperation'. Prozess SpielOGLProject1.exe (972)"


Das ganze passiert, weil der Speicherplatz schon bei levels[1] feigegeben wird; das habe ich verstanden, nur habe ich keine Idee, wie ich das Problem ordentlich umgehen könnte

mkinzler 11. Jul 2010 14:26

AW: free erzeugt Fehler
 
Beim Löschen immer von Hinten, denn mit jedem Löschen, wird die Anzahl der Elemente ja kleiner
Delphi-Quellcode:
for i := high(levels) to low(level) do
     levels[i].free;

Björn Ole 11. Jul 2010 14:30

AW: free erzeugt Fehler
 
Er löscht ja nicht, er gibt ja nur frei.

Versuchs mal mit FreeAndNil(levels[i]) und prüfe davor auf Assigned(levels[i]).

daywalker9 11. Jul 2010 14:32

AW: free erzeugt Fehler
 
Free prüft auch ob die Klasse <> NIL ist

Björn Ole 11. Jul 2010 14:48

AW: free erzeugt Fehler
 
Ja, Free setzt aber nichts auf nil.

Mir ist aber gerade aufgefallen, dass das gar nichts mit dem Problem zu tun hat.

daywalker9 11. Jul 2010 14:49

AW: free erzeugt Fehler
 
Ging ja auch nur um das assigned()..

fui-tak 11. Jul 2010 14:58

AW: free erzeugt Fehler
 
Eure Vorschläge funktionieren alle leider nicht:

Erster Versuch:
Delphi-Quellcode:
for i := 0 to high(levels) do
  if Assigned(levels[i]) then
     FreeAndNil(levels[i]);


Dieser Code gibt zwar keinen Fehler aus, aber die Schleife wird auch nur einmal durchgegangen
Delphi-Quellcode:
for i := high(levels) to low(levels) do
  levels[i].free;


Hier gibt's dann wieder einen Fehler
Delphi-Quellcode:
for i := high(levels) downto low(levels) do
  levels[i].free;

daywalker9 11. Jul 2010 15:04

AW: free erzeugt Fehler
 
Ansonsten bastel dir eine Assign Methode, um alle Eigenschaften in das Level zu kopieren. Dann kannst du diese Klassen so freigeben. Beispiel:

Delphi-Quellcode:
level[0]:=TLevel.create;
level[0].Assign(level[1]);


procedure TLevel.Assign(ASOurce:TPersistent);
begin if (ASource is TLevel) then
         Self.Name := (ASOurce as TLevel).Name; //für alle attribute machen
      else
         inherited Assign(ASOurce);
end;
Du musst dann TLevel von TPersistent ableiten

xZise 11. Jul 2010 15:08

AW: free erzeugt Fehler
 
Moin,
naja der Fehler ist ja klar: Es wird vorher schon bereits ein weiter hinten liegendes Element gelöscht. Da hilft dann FreeAndNil() auch wenig, da nicht der hinten liegende Zeiger genilt wird (oder liege ich da falsch).

Deshalb würde ich in diesem Fall echt assign verwenden!

MfG
Fabian

DeddyH 11. Jul 2010 16:47

AW: free erzeugt Fehler
 
Eine andere Möglichkeit sehe ich auch nicht, da level[3] ja nicht mitbekommt, wenn level[1] freigegeben wird, egal ob mit Free oder FreeAndNil. Ansonsten müsste man ja irgendwo hinterlegen, wo überall gleiche Instanzverweise existieren und diese dann beim Freigeben alle nullen, aber das halte ich für ein sehr gefährliches und fehleranfälliges Unterfangen.

himitsu 11. Jul 2010 17:44

AW: free erzeugt Fehler
 
Der Spruch "Es kann nur Einen geben", trifft halt an vielen Stellen zu.

Wenn du über das Array die Objekte freigeben willst, dann ist das Array, bzw. sind die einzelnen Felder quasi der Owner ihrer zugeordneten Objekte.
Tja, und bei Objekten darf es halt nur einen Besitzer geben, welcher für die Freigabe zuständig ist, es sei denn die anderen "owner" werden beim Löschen benachrichtigt, daß das gelöschte Objekt nun weg ist und sie es aus ihrer Liste entfernen sollen.

mkinzler 11. Jul 2010 17:46

AW: free erzeugt Fehler
 
Eine Objektliste kann Eigentümer der Objekte sein, aber ein Array? :gruebel:

himitsu 11. Jul 2010 17:51

AW: free erzeugt Fehler
 
Ob du nun einer Objektliste sagst, sie solle sich um das Löschen kümmern
oder ob man sich selber bei einer Liste/Array um das Löschen kümmer,
ist hierbei unbedeutend.

Der Owner ist einfach nur für die Freigabe/Löschen zuständig ... egal, wer da nun löscht.

Hier ist es halt so, daß 2 Felder des Arrays dafür zuständig gemacht wurden ... das kommt auf's Selbe raus, als wenn man dieses Objekt zweimal in eine Objektliste stecken würde und diese dann alles freigeben soll.

ChrisE 12. Jul 2010 08:32

AW: free erzeugt Fehler
 
Hallo,

eine Möglichkeit wäre es doch vor dem Free erst mal alle Einträge auf "gleichheit" zu prüfen und nur die in eine Zu-Löschen-Liste zu packen die nicht identisch sind. Diese wird dann eben durchlaufen und deren Objekte frei gegeben.

Nur so anbei.

Greez, Chris

Sir Rufo 12. Jul 2010 08:43

AW: free erzeugt Fehler
 
Benutze eine separate TObjectList (OwnsObjects auf True) um dort die Level-Instanzen zu speichern.
In deinem Array kannst du dann diese Instanzen sooft verwenden wie du möchtest.
Beim Beenden des Programms einfach nur die TObjectList mit Free aus dem Speicher entfernen und der Drops ist gelutscht.

dominikkv 12. Jul 2010 10:40

AW: free erzeugt Fehler
 
http://www.delphipraxis.net/152901-m...ml#post1034913

fui-tak 12. Jul 2010 11:47

AW: free erzeugt Fehler
 
Danke an alle für die flotten Antworten!!

Ich habe jetzt die Lösung von Sir Rufo mit der TObjectList gewählt und es klappt ohne Probleme :thumb:


Alle Zeitangaben in WEZ +1. Es ist jetzt 18:18 Uhr.

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