AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Sprachen und Entwicklungsumgebungen Object-Pascal / Delphi-Language Delphi Pointer existiert, das Objekt dahinter nicht. Wie zuverlässig prüfen?
Thema durchsuchen
Ansicht
Themen-Optionen

Pointer existiert, das Objekt dahinter nicht. Wie zuverlässig prüfen?

Ein Thema von uups · begonnen am 4. Feb 2019 · letzter Beitrag vom 7. Feb 2019
Antwort Antwort
Seite 2 von 3     12 3      
freimatz

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

AW: Pointer existiert, das Objekt dahinter nicht. Wie zuverlässig prüfen?

  Alt 5. Feb 2019, 09:33
Habe ein interface das ein anderes inplementiert. Hole mit von dem Objekt das andere interface, und plötzlich ist das Objekt weg.
Dann machst du vielleicht was falsch?
Klar. An Code von anderen Leuten rum machen
Ich wollte damit nur sagen dass interfaces auch kein Allheilmittel sind. Aber ich verwende die auch gerne weil man normalerweise sich dann keine Gedanken mehr machen muss und wenn da ein Pointer noch eine Referenz drauf hält das Objekt gar nicht freigegeben wird.
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.580 Beiträge
 
Delphi 11 Alexandria
 
#12

AW: Pointer existiert, das Objekt dahinter nicht. Wie zuverlässig prüfen?

  Alt 5. Feb 2019, 09:35
Tja, hilft auch nicht immer. Gerade size ich an so einem Fall. Habe ein interface das ein anderes inplementiert. Hole mit von dem Objekt das andere interface, und plötzlich ist das Objekt weg.
Das hört sich so an als ob da Objektreferenzen mit Interfacereferenzen gemischt werden. Der einfachste Fall:
Delphi-Quellcode:
procedure Example(const AData: IBlub);
begin...end;

Example(TMySuperObject.Create);
In diesem Fall geht die Referenzzählung schief, da durch das const die Referenzzählung deaktiviert wird. Nach der Erstellung des Objekts wäre es aber gut, wenn der Referenzzähler einmal erhöht würde. Gibt man nämlich innerhalb der aufgerufenen Methode (Example) das Objekt weiter oder speichert die Referenz irgendwo, ist das Objekt dahinter ggf. plötzlich weg, denn der Zähler ist dann ggf. 0.

Insofern gibt es schon Konstellationen, in denen Fehler in der Referenzzählung, die man beim Programmieren macht, nicht so einfach auffallen. Wenn man nicht schon einmal über den genannten Fall gestolpert ist, wird das vermutlich auch nicht so schnell auffallen beim Überlesen des Quelltextes.

Klar. An Code von anderen Leuten rum machen
Ich wollte damit nur sagen dass interfaces auch kein Allheilmittel sind.
Es ist wie mit reinen Objekten... Solange der Quelltext sauber geschrieben ist gibt es auch kaum Probleme.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
hanvas

Registriert seit: 28. Okt 2010
166 Beiträge
 
Delphi 11 Alexandria
 
#13

AW: Pointer existiert, das Objekt dahinter nicht. Wie zuverlässig prüfen?

  Alt 5. Feb 2019, 09:39

Es gibt mehrere Ansätze, von denen aber keiner zuverlässig ist, denn der freigegebene Speicher kann ja inzwischen anderweitig verwendet worden sein:
Dort wo es notwendig ist, und das ist es selten, kann man einen Ansatz verwenden der Deine Methoden kombiniert und mit sehr hoher Wahrscheinlichkeit auch funktioniert wenn Speicherbereiche nicht überschrieben bzw. überschrieben wurde.

Ich leite von einer (Ur) Klasse ab, bei der jedes Objekt eine eindeutige Identität in einem Feld und in einem anderen Feld den Zustand speichert.

Der Constructor sorgt dafür das Identität und Zustand korrekt gesetzt werden, der Destrutor überschreibt den Zustand. Da der Offset der beiden Felder im Speicher bekannt ist, kann ich auch bei freigegebenen Objekten bei denen der Speicher nocht nicht überschrieben wurde prüfen ob diese noch existieren, und bei freigegebenen überschriebenen Objekten hingegen ist sehr unwahrscheinlich das beide Felder zufällig so überschrieben werden das diese Sinn ergeben.

cu Ha Joe
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
1.442 Beiträge
 
Delphi 11 Alexandria
 
#14

AW: Pointer existiert, das Objekt dahinter nicht. Wie zuverlässig prüfen?

  Alt 5. Feb 2019, 13:13
Geht nur bei eignen Klassen, aber nicht z.B. bei der VCL. Aber immerhin.

Erwähnen möchte ich noch, dass madexcept hat die Möglichkeit hat, Speicherzugriffe abzusichern. Damit kann man u.U. Probleme in dem Bereich finden. Allerdings ist das extrem langsam und verbraucht viel Speicher.
  Mit Zitat antworten Zitat
jus

Registriert seit: 22. Jan 2005
344 Beiträge
 
Delphi 2007 Professional
 
#15

AW: Pointer existiert, das Objekt dahinter nicht. Wie zuverlässig prüfen?

  Alt 6. Feb 2019, 22:51
Wenn man so etwas braucht, sollte man mit Interfaces arbeiten.

Man kann auch schauen, ob man statt den Originalpointer weiterzugeben nur Kopien weiterreichen kann. Das geht nicht immer, wäre aber eine gute Lösung. So wird es ja z.B. mit TPicture schon gemacht. Da wird eine Zuweisung zu einem Assign umgebogen.
Hallo,

ich muß zugeben, dass ich eigentlich noch ein Anfänger in Interfaces bin. Mich würde der Ansatz mit Interfaces sehr interessieren, wie man dann testen kann, ob das Objekt schon freigegeben wurde? Sprich, macht man dann einfach zu einem Objekt noch einen Wrapper Interface und testet man dann mit "if assigned(Interfacevariable) then", ob das Objekt bereits freigegeben wurde? Könnte wer da ein kurzes Beispiel dazu posten?

lg,
jus
  Mit Zitat antworten Zitat
Schokohase
(Gast)

n/a Beiträge
 
#16

AW: Pointer existiert, das Objekt dahinter nicht. Wie zuverlässig prüfen?

  Alt 6. Feb 2019, 23:13
Mit Interfaces brauchst du nicht mehr testen, denn die Instanz wird erst freigegeben, wenn du die Instanz vergessen hast.
Delphi-Quellcode:
var
  foo, foo1, foo2: IFoo;
begin
  foo := TFoo.Create;
  foo1 := foo;
  foo2 := foo;
  foo := nil;
  foo1 := nil;
  foo2 := nil; // Hier erfolgt jetzt automatisch die Freigabe der Instanz
end;
Und wenn man nicht mehr weiß wonach man sucht, wie will man dann feststellen ob es noch existiert ...

Geändert von Schokohase ( 6. Feb 2019 um 23:15 Uhr)
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
8.275 Beiträge
 
Delphi 10.4 Sydney
 
#17

AW: Pointer existiert, das Objekt dahinter nicht. Wie zuverlässig prüfen?

  Alt 7. Feb 2019, 00:07
Hallo,
Einspruch

Zitat:
foo2 := nil; // Hier erfolgt jetzt automatisch die Freigabe der Instanz
Das glaube ich nicht (weiß es aber auch nicht).

Die Freigabe erfolgt doch erst, wenn die Interface-Variable ihren Scope verläßt?
In diesem Fall hinter dem abschließenden end?

Oder wird das durch das nil-Setzen vorgezogen?
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe
Online

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

AW: Pointer existiert, das Objekt dahinter nicht. Wie zuverlässig prüfen?

  Alt 7. Feb 2019, 00:13
Die Freigabe erfolgt doch erst, wenn die Interface-Variable ihren Scope verläßt?
In diesem Fall hinter dem abschließenden end?
Eigentlich erzeugt der Compiler unsichtbaren Code der bei Verlassen des Scopes alle Interface-Variablen auf nil setzt. Man kann die Variable aber schon vorher auf nil setzen. Ob damit tatsächlich die Instanz freigegeben wird hängt davon ab ob noch andere Referenzen darauf existieren.

Übrigens muss es nicht mal nil sein. Auch das Zuweisen einer anderen Interface-Instanz an diese Variable würde den Referenzzähler der vorigen Instanz herunterzählen, so wie es den der neuen hochzählt.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Aviator

Registriert seit: 3. Jun 2010
1.611 Beiträge
 
Delphi 10.3 Rio
 
#19

AW: Pointer existiert, das Objekt dahinter nicht. Wie zuverlässig prüfen?

  Alt 7. Feb 2019, 00:14
Oder wird das durch das nil-Setzen vorgezogen?
Ja wird es. Da der Referenzzähler an dieser Stelle um 1 dekrementiert wird und dadurch der Referenzzähler den Wert 0 erreicht. Ist der Zähler 0, wird das Object freigegeben. Unabhängig, ob man noch im aktuellen Scope der Function/Procedure ist oder nicht.

Mach dir doch schnell mal ein kleines Konsolenprojekt mit einer Klasse die ein Interface implementiert und den Destructor überschreibt. Dort einen Breakpoint rein und schauen, wann der Debugger dort anhält. Somit kannst du das ganz leicht testen.
  Mit Zitat antworten Zitat
jus

Registriert seit: 22. Jan 2005
344 Beiträge
 
Delphi 2007 Professional
 
#20

AW: Pointer existiert, das Objekt dahinter nicht. Wie zuverlässig prüfen?

  Alt 7. Feb 2019, 00:27
Mit Interfaces brauchst du nicht mehr testen, denn die Instanz wird erst freigegeben, wenn du die Instanz vergessen hast.
Delphi-Quellcode:
var
  foo, foo1, foo2: IFoo;
begin
  foo := TFoo.Create;
  foo1 := foo;
  foo2 := foo;
  foo := nil;
  foo1 := nil;
  foo2 := nil; // Hier erfolgt jetzt automatisch die Freigabe der Instanz
end;
Und wenn man nicht mehr weiß wonach man sucht, wie will man dann feststellen ob es noch existiert ...
ehm... mir es ist eigentlich klar, dass man bei com Interfaces der Compiler da automatisch freigibt, wenn es nicht mehr im Scope ist. Nutze ich ehrlich gesagt sehr gerne. Doch die eigentliche Frage ist ja, wie man mit Hilfe von Interfaces mitten im Programm überprüfen kann, ob das Objekt noch da ist und ohne dass man das mit dem Marker auf NIL setzt. Mit dem NIL-Marker setzen hätte man ja kein Interface benötigt.

Geändert von jus ( 7. Feb 2019 um 00:31 Uhr)
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 2 von 3     12 3      


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