Thema: Delphi IsObject / IsClass

Einzelnen Beitrag anzeigen

Benutzerbild von negaH
negaH

Registriert seit: 25. Jun 2003
Ort: Thüringen
2.950 Beiträge
 
#3

Re: IsObject / IsClass

  Alt 3. Feb 2004, 21:01
Ich weiß nicht welchen Code du von IsObject() von mir analysiert hast. Meine isObject() Funktion fragt nicht ab ob der Speicherzeiger ein Magic enthält. Dies darf er auch garnicht, da es ja nicht gesagt ist das der Borland MM benutzt wird. IsObject() überprüft so wie die Borland Funktion "is" ob es sich um ein gültiges Object abgeleitet von TObject handelt. Dabei lädt sie die VMT der Objectinstance und überprüft ab da rekursiv die Klassentypen bis hinab zu TObject. Somit ist IsObject fast identisch wie IsClass(). Allerdings, habe ich eine andere Assembler Routinie als Ersatz für "is" benutzt, die eben SICHER gegen nil Pointer in den VMT's ist. Dies ist beim Borland Original "is" Operator NICHT der Fall. Zusätzlich zu dem habe ich noch einen try except Block eingebaut um eventuelle AV's abzufangen.

Aber grundsätzlich gibts für deine Problem keine saubere Lösung, das stimmt.
Man kann noch eine Verbesserung durchführen indem man TObject.FreeInstance() überschreibt oder eben hookt/patcht. Die neue .FreeInstance Klassenmethode gibt so wie die originale den Speicher frei, überschreibt aber vorher mit FillChar(Self^, Self.InstanceSize) den Speicher des Objectes mit Nullen. Da Self^^ ein Zeiger auf die Klasse des Objectes ist, heist dies das nun der IS Operator auf einen NIL Zeiger zur VMT des Objectes zugreift. In diesem Moment wird also nochmal ca. 50% die Wahrscheinlichkeit erhöht falsche Objecte zu finden.

Allerdings, dies hilft dir nur im Beispiel deines obigen Codes. Nach dem Object.Free ist nämlich Object^ = Object.PointerToClass == NIL. Würdest du aber sofort nach dem .Free wiederum ein Object erzeugen, mit gleicher Größe wie das vorherige, so benutzt der Speichermanager exakt den Speicher des vorher freigegeben Objectes erneut. Somit befindet sich an der Speicheradresse von Object nun wieder ein gültiges Object, es IST aber NICHT das gleiche Object !!

also:

Delphi-Quellcode:
var
  A,B: TMyObject;
begin
  A := TMyObject.Create(1);
  A.Free;
  if not IsObject(A) then
    "Alles Ok !"

  B := TMyObject.Create(2);
  if A = B then
    "sehr wahrscheinlicher Fall das A = B ist da MM Speicher wiederverwendet"

  if IsObject(A) then
    "Integer(A) = Integer(B), aber NICHT das gleiche Object"
end;
Gruß Hagen
  Mit Zitat antworten Zitat