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?

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 1 von 3  1 23   
uups

Registriert seit: 23. Aug 2004
59 Beiträge
 
#1

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

  Alt 4. Feb 2019, 15:42
Delphi-Version: 10.2 Tokyo
Hallo!

Sagen wir, es gibt ein Objekt und ein Pointer, das auf dieses Objekt zeigt. Irgendwann wird das Object freigegeben, Pointer zeigt aber immer noch darauf. Die Prüfung mit Assigned(Pointer) ist erfolgreich und erst beim Versuch, auf das Object dahinter zuzugreifen kommt die AV.

Gibt es eine zuverlässige Möglichkeit zu prüfen, ob ein Objekt hinter einem "gültigen" Pointer noch existiert?
  Mit Zitat antworten Zitat
Benutzerbild von Neutral General
Neutral General

Registriert seit: 16. Jan 2004
Ort: Bendorf
5.032 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#2

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

  Alt 4. Feb 2019, 16:02
Nein gibts nicht*

*) Vielleicht mit großem Aufwand und viel Gematsche (ich glaube wir hatten so nen Thread irgendwann schon mal) aber es lohnt sich nicht.
Michael
"Programmers talk about software development on weekends, vacations, and over meals not because they lack imagination,
but because their imagination reveals worlds that others cannot see."
  Mit Zitat antworten Zitat
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
444 Beiträge
 
Delphi 2007 Professional
 
#3

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

  Alt 4. Feb 2019, 16:07
Sagen wir, es gibt ein Objekt und ein Pointer, das auf dieses Objekt zeigt. Irgendwann wird das Object freigegeben, Pointer zeigt aber immer noch darauf. Die Prüfung mit Assigned(Pointer) ist erfolgreich und erst beim Versuch, auf das Object dahinter zuzugreifen kommt die AV.

Gibt es eine zuverlässige Möglichkeit zu prüfen, ob ein Objekt hinter einem "gültigen" Pointer noch existiert?
Kurze Antwort: Nein.

Es gibt mehrere Ansätze, von denen aber keiner zuverlässig ist, denn der freigegebene Speicher kann ja inzwischen anderweitig verwendet worden sein:

1. Man könnte überprüfen, ob ClassName immernoch den erwarteten Wert liefert. Problem: Solange der Speicher nicht neu verwendet wurde, funktioniert das auch nach der Freigabe. Wurde er neu verwendet, kann das eine andere Intanz derselben Klasse sein, so dass man auch hier nicht zuverlässig herausfindet, ob es noch dasselbe Objekt ist. Und dann kann der Speicher so verwendet worden sein, dass der Aufruf von ClassName zu unvorhersehbaren Ergebnissen führt. Am häufigsten eine Access Violation, aber es sind auch andere Fehler möglich. Z.B. könnte eine völlig andere Methode aufgerufen werden, die das Bankkonto des Anwenders leerräumt, Pornos an seine Frau schickt und das BKA ruft.

2. Man könnte Felder mit bekanntem Inhalt überprüfen. Ob das funktioniert ist natürlich abhängig von der Klasse. Z.B. könnte die Länge eines dynamischen Arrays, das im Constructor gesetzt wird, überprüfen, oder ein Feld mit einem Interface oder einem String, welches im Constructor gesetzt wird. Wenn das Feld nicht den erwarteten Wert hat, ist das Objekt nicht gültig. Problem: Es könnte ein anderes Objekt dort liegen, dessen Felder zufällig ebenfalls gültige Werte haben. Auch der Zugriff auf diese Felder könnte zu Nebenwirkungen führen, z.B. AVs.

3. In Abwandlung von 2. könnte man ein Feld vorsehen und mit klassenspezifschem Inhalt + einen Instanzspezifischen Inhalt (z.B. einer laufenden Nummer) füllen. So kann man theoretisch prüfen, ob das Objekt die richtige Klasse hat und ob es noch das alte ist (Wobei letzteres voraussetzt, dass man weiss, welchen Inhalt die Instanz haben soll, woher weiss man das? Z.B. indem man neben dem Pointer immer auch die Laufende Nummer des Objekts in einem Record speichert.). Auch hier kann es zu Fehlern beim Zugriff kommen.

4. Man könnte die Verwaltungsstrukturen des Memory-Mangers durchgehen und nachssehen, ob der Pointer noch auf belegten Speicher zeigt. Hilft nur bedingt, denn der Speicher könnte ja schon wieder anderweitig verwendet worden sein.

5. Man könnte die Speicherverwaltung für seine Objekte selbst übernehmen und dafür sorgen, das Speicher niemals wieder verwendet wird. Der Destructor füllt dann den Speicher des Objekts mit z.B. 0en, so dass man tatsächlich feststellen kann, ob ein Objekt noch gültig ist. Das dürfte sogar funktionieren, aber verschwendet eine Menge Speicher.

Und all das berücksichtig noch nicht einmal Multithreading.

Oder kurz: Zuverlässig geht das nicht.
Thomas Mueller

Geändert von dummzeuch ( 4. Feb 2019 um 16:10 Uhr)
  Mit Zitat antworten Zitat
MichaelT

Registriert seit: 14. Sep 2005
Ort: 4020 Linz
483 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#4

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

  Alt 4. Feb 2019, 16:43
Nein.

Du musst selbst dafür sorgen, dass die Referenz auf NIL (Not in List) gesetzt wird oder gültig bleibt.

Alles andere führt zu einem Verwaltungsaufwand der noch dazu dein Klassendesign beeinträchtigt von der Programmarchitektur ganz zu schweigen. Transparent geht es nicht. Am Ende läuft jede Strategie drauf hinaus indirekte Referenzen zu halten, die Klasse am Ende ihre Objekte selbst verwaltet und den Overhead muss man aufwiegen mit der Vereinfachung anderorts bspw. beim Iterieren über Container. Proxyobjekte oder Nullobjekte usw...

Du kannst bspw. das Auftreten solcher Situation zu vermeiden mit TObjectList arbeiten. In Delphi gilt an sich das Vermeiden dieser Abfrage als geboten.



Hallo!

Sagen wir, es gibt ein Objekt und ein Pointer, das auf dieses Objekt zeigt. Irgendwann wird das Object freigegeben, Pointer zeigt aber immer noch darauf. Die Prüfung mit Assigned(Pointer) ist erfolgreich und erst beim Versuch, auf das Object dahinter zuzugreifen kommt die AV.

Gibt es eine zuverlässige Möglichkeit zu prüfen, ob ein Objekt hinter einem "gültigen" Pointer noch existiert?
  Mit Zitat antworten Zitat
hoika

Registriert seit: 5. Jul 2006
Ort: Magdeburg
7.104 Beiträge
 
Delphi XE4 Professional
 
#5

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

  Alt 4. Feb 2019, 16:48
Hallo,
gibt es, aber nicht für lau und nur, wenn sich der gesamte beteiligte Code dran hält.

Die Objekte mit den Pointer müssen sich beim eigentlichen Objekt registrieren,
das eigentliche informiert dann, wenn es freigegeben wird.
Dann müssen die Pointer-Objekte ihren Pointer auf nil setzen.
Heiko
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
6.810 Beiträge
 
Delphi 10.3 Rio
 
#6

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

  Alt 4. Feb 2019, 21:00
So wie TComponent das macht: System.Classes.TComponent.FreeNotification

Funktioniert halt nur mit TComponent, aber nicht mit beliebigen TObject-Abkömmlingen.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
7.207 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#7

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

  Alt 5. Feb 2019, 06:42
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.
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
552 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

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

  Alt 5. Feb 2019, 07:57
Wenn man so etwas braucht, sollte man mit Interfaces arbeiten.
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.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
6.810 Beiträge
 
Delphi 10.3 Rio
 
#9

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

  Alt 5. Feb 2019, 08:26
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?
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
444 Beiträge
 
Delphi 2007 Professional
 
#10

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

  Alt 5. Feb 2019, 08:32
Wenn man so etwas braucht, sollte man mit Interfaces arbeiten.
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.
Lass mich raten: Du mischst Objekte und Interfaces? Also etwa so:

Delphi-Quellcode:
obj := TMyObject.Create;
Int1 := obj as IInterface1;
// oops, ich brauche ein anderes
Int1 := nil; // weg mit Int1, das brauche ich nicht mehr (*1)
Int2 := obj as IInterface2; // -> boom
*1 hier wird dein Objekt freigegeben, da es keine Interface-Referenz mehr darauf gibt.

Sowas zu mischen ist fast immer eine schlechte Idee.

Hol Dir doch von dem "falschen" Interface einfach das benoetigte.

Delphi-Quellcode:
Int2 := Int1 as Interface2;
Int1 := nil;
Thomas Mueller
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 3  1 23   

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 21:39 Uhr.
Powered by vBulletin® Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2019 by Daniel R. Wolf