AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Delphi Objekte / Freigaben / Free / Nil

Objekte / Freigaben / Free / Nil

Ein Thema von Alex_ITA01 · begonnen am 9. Okt 2013 · letzter Beitrag vom 10. Okt 2013
Antwort Antwort
Namenloser

Registriert seit: 7. Jun 2006
Ort: Karlsruhe
3.724 Beiträge
 
FreePascal / Lazarus
 
#1

AW: Objekte / Freigaben / Free / Nil

  Alt 9. Okt 2013, 20:43
Das ist ja nur eine Minianwendung wo es recht übersichtlich ist. Wie kann man denn ganz sicher die Objekte freigeben und falls jemand anderes (vielleicht ein parallel laufender Thread) diese auf Gültigkeit abfragt auch wirklich feststellen, dass man noch drauf zu greifen kann?!
Geht nicht. Musst du anders lösen, z.B. über ein Observer-Pattern.

Und Multi-Thread ist noch mal eine Sache für sich...
  Mit Zitat antworten Zitat
Alex_ITA01

Registriert seit: 22. Sep 2003
1.134 Beiträge
 
Delphi 12 Athens
 
#2

AW: Objekte / Freigaben / Free / Nil

  Alt 9. Okt 2013, 21:20
@jaenicke: Das war ja auch der Vorschlag von Uwe Raabe aber das Endergebnis ist ja das gleiche. Ich kann nicht erkennen, ob das Objekt noch da ist oder nicht.

Sowohl in meinem Beispiel in Post 1 als auch die Variante mit OwnsObjects wird mir mit ReportOnMemoryLeaks auch kein Speicherleck abgezeigt.
Ist ja schön wenn das auch so ist aber ich verstehe nur nicht, warum ich auf alle Eigenschaften und Variablen des Objekts zugreifen kann obwohl es eigentlich freigegeben wurde.
Gibt es keine Variante, dass Objekt so freizugeben, dass eine if Assigned Abfrage dann auch wirklich "False" liefert?

Gruß
Let's fetz sprach der Frosch und sprang in den Mixer
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Objekte / Freigaben / Free / Nil

  Alt 9. Okt 2013, 21:41
Gibt es keine Variante, dass Objekt so freizugeben, dass eine if Assigned Abfrage dann auch wirklich "False" liefert?
Solange du die besagte Variable nicht selbst auf nil setzt, nein. Dein Problem ist, daß mehrere Variablen auf dasselbe Objekt verweisen. Wird dieses Objekt freigegeben, zeigen alle diese Variablen auf einen ungültigen Speicherbereich. Das kannst du ohne erheblichen Aufwand nicht vermeiden. Schon gar nicht im Multithread-Bereich.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.358 Beiträge
 
Delphi 11 Alexandria
 
#4

AW: Objekte / Freigaben / Free / Nil

  Alt 9. Okt 2013, 21:41
Das Problem ist nicht so einfach zu lösen.

Hier mal ein paar ältere Diskussionen dazu:
http://www.delphipraxis.net/166899-i...eferenzen.html
http://www.delphipraxis.net/159095-r...e-objekte.html
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Alex_ITA01

Registriert seit: 22. Sep 2003
1.134 Beiträge
 
Delphi 12 Athens
 
#5

AW: Objekte / Freigaben / Free / Nil

  Alt 9. Okt 2013, 21:43
Ok danke für die Info. Wo wäre denn die richtige Stelle zum Nil setzen, wenn ich es selber machen muss @Uwe?

Gruß
Let's fetz sprach der Frosch und sprang in den Mixer
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

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

AW: Objekte / Freigaben / Free / Nil

  Alt 9. Okt 2013, 23:26
Ok danke für die Info. Wo wäre denn die richtige Stelle zum Nil setzen, wenn ich es selber machen muss @Uwe?
Nach deinem gezeigten Code zu urteilen, wäre folgende Code-Sequenz im FormDestroy korrekt:

Delphi-Quellcode:
procedure TForm4.FormDestroy(Sender: TObject);
begin
  tmpObject := nil;
  MyObjList.Free;
  MyObjList := nil;
end;

Die beiden if-Anweisungen würden demnach immer fehlschlagen und der dahinter liegende Code kann somit eliminiert werden. Solange die beiden Variablen nicht noch anderswo verwendet werden, braucht man sie dann aber auch nicht auf nil setzen. Damit reduziert sich das FormDestroy auf ein simples MyObjList.Free;

Ich vermute aber, daß dein eigentlicher Code etwas ganz anderes macht. Dazu kann ich so natürlich nichts sagen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Thom

Registriert seit: 19. Mai 2006
570 Beiträge
 
Delphi XE3 Professional
 
#7

AW: Objekte / Freigaben / Free / Nil

  Alt 10. Okt 2013, 01:45
Das Problem ist nicht so einfach zu lösen.

Hier mal ein paar ältere Diskussionen dazu:
http://www.delphipraxis.net/166899-i...eferenzen.html
Wie die Zeit vergeht...
Auf den diesjährigen Delphi-Tagen hatte ich dazu übrigens die Funktionsweise live im Debugger demonstriert.
Es funktioniert also - wenn auch (momentan) nur unter Windows, da dazu intern Assemblerfunktionen verwendet werden.
Thomas Nitzschke
Google Maps mit Delphi
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
10.072 Beiträge
 
Delphi 12 Athens
 
#8

AW: Objekte / Freigaben / Free / Nil

  Alt 10. Okt 2013, 06:35
In den meisten Anwendungsfällen sind in so einem Fall aber eher Interfaces passend. Dann braucht man sich nicht darum zu kümmern und das Objekt wird freigegeben, wenn es von keiner Seite mehr benutzt wird. Umgekehrt hat man es aber auch überall noch, auch wenn es in der ursprünglichen Liste schon weg ist.
Sebastian Jänicke
AppCentral
  Mit Zitat antworten Zitat
Alex_ITA01

Registriert seit: 22. Sep 2003
1.134 Beiträge
 
Delphi 12 Athens
 
#9

AW: Objekte / Freigaben / Free / Nil

  Alt 10. Okt 2013, 07:32
Danke für die zahlreichen Hinweise.
Ich habe nur noch zwei letzte Fragen

Aktuell habe ich die Variante mit den OwnsObjects aktiv und im FormDestroy rufe ich zur Zeit nur "FreeAndNil(MyObjList);" auf. Ich habe jetzt ja gelernt, dass dann das globale Objekt "tmpObject" noch vorhanden ist aber auf ein ungültigen Speicherbereich zeigt.

1) Woher weiß der Speichermanager eigentlich, dass diese Speicheradresse "ungültig" ist? Gibt es da irgendein Flag dafür?
2) Das das "if Assigned(tmpObject) then" weiterhin nach "FreeAndNil(MyObjList);" im FormDestroy funktioniert, habe ich verstanden aber warum crasht das Programm nicht, wenn ich dann auch auf die Inhalte und Funktionen von "tmpObject" zugreife nach der "if Assigned(tmpObject) then"-Abfrage?

Gruß
Let's fetz sprach der Frosch und sprang in den Mixer
  Mit Zitat antworten Zitat
Benutzerbild von stahli
stahli

Registriert seit: 26. Nov 2003
Ort: Halle/Saale
4.358 Beiträge
 
Delphi 11 Alexandria
 
#10

AW: Objekte / Freigaben / Free / Nil

  Alt 10. Okt 2013, 08:26
Wenn Du ein Objekt freigibst wird nur der Speicherbereich als verfügbar definiert.

Wenn Du jetzt noch darauf zugreifst und der Speicher noch nicht überschreiben wurde, dann kann das noch gut gehen.
Es kann aber auch sein, dass es in unvorhergesehener Form knallt, wenn die dort stehenden Binärdaten schon (teilweise) überschreiben wurde.


In meinem aktuellen Framework habe ich übrigens folgende Lösung:

In der Datanschicht sammle ich alle erzeugten Objekte in einer sortiereten Liste.
Diese fordere ich dann zur Laufzeit anhand einer Id an. Durch Binary Search geht das wirklich schnell.
Wurde ein Objekt bereits aufgelöst, gibt die Anfrage nil zurück.
Man muss dann halt immer wieder die Objekte "abfordern".

Die Objekte müssen dafür dann auch speziell angepasst sein.
So funktioniert das gut, aber halt nur in einem festgelegten Rahmen.

Delphi-Quellcode:
function TssIO_Custom.GetObject(Id: TssId): TssObject;
var
  Index: Integer;
  ssObj: TssObject;
begin
  Result := nil;
  ssObj := TssObject.Create(nil, Id, True);
  if ssObjectList.BinarySearch(ssObj, Index) then
    Result := ssObjectList[Index];
  FreeAndNil(ssObj);
end;

procedure TssIO_Custom.RegisterObject(ssObj: TssObject);
var
  Index: Integer;
begin
  if not Assigned(ssObj) then
    Exit;
  if ssObj.HideMode then
    Exit;
  if not ssObjectList.BinarySearch(ssObj, Index) then
    ssObjectList.Insert(Index, ssObj);
end;

procedure TssIO_Custom.UnregisterObject(ssObj: TssObject);
begin
  if not Assigned(ssObj) then
    Exit;
  if ssObj.HideMode then
    Exit;
  ssObjectList.Extract(ssObj);
end;

Eine Compilerlösung, Referenzen auf aufgelöste Objekte automatisch zu nilen ist wohl nicht in Aussicht.
Stahli
http://www.StahliSoft.de
---
"Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004)
  Mit Zitat antworten Zitat
Antwort Antwort

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

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 17:45 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