Einzelnen Beitrag anzeigen

dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
424 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