![]() |
Delphi-Version: XE2
Schutzverletzung bei Zugriff auf Objekt
Hallo,
nach mehrstündiger Suche hab ich noch immer keinen Deut und hoffe auf Hinweise: Der Fehler ist eine Schutzverletzung, sobald ich auf ein objekt zugreife. Eine Prüfung "if assigned(sd)" nutzt nichts, da geht er darüber. Das Objekt selber ist in eine andere Klasse gepackt. Sinngemäß sieht das so aus:
Delphi-Quellcode:
naturgemäß ist das nicht der Originalcode. Komisch nun ist, dass ProzedurX klappt, ProzedurY nicht. Beide machen nicht mehr, als auf das eingebettete Objekt zuzugreifen. Erzeugt wird das ObjektB im Create von ObjektA. Und ich kann auch darauf zugreifen, etwa in Prozedur X, aber auch von aussen (aus dem mainform), nur nicht aus ProzedurY heraus.
ObjektA.ObjektB.ParameterA := s;
ObjektA.ProzedurX; ObjektA.ProzedurY; procedure ProzedurX; begin ObjektB.ParameterB := x; end; procedure ProzedurY; begin ObjektB.ParameterB := y; end; Mir ist klar, dass man damit noch keine Lösung ableiten kann, aber gleich alle Klassen posten ist halt auch nicht einfacher. danke für Hinweise, wo ich suchen könnte gruß tom |
AW: Schutzverletzung bei Zugriff auf Objekt
ps. Wenn ich die beiden Klassen herausziehe und in ein leeres Testprojekt stecke, dann klappen übrigens auch die beiden Prozedur-Aufrufe, es muss also irgendeine Querabhängigkeit sein.
Hmm, ich weiss, damit wird man nicht schlauer ... |
AW: Schutzverletzung bei Zugriff auf Objekt
Zitat:
Schutzverletzungen treten meist auf, wenn man auf etwas zugreifen will, das NIL ist. |
AW: Schutzverletzung bei Zugriff auf Objekt
Da die Assigned()-Prüfungen nicht greifen, scheint das Objekt ja nicht einmal NIL zu sein. Es hat den Anschein, dass es irgendwann vorher freigegeben, aber eben nicht genullt wurde, so dass man auf einen Dangling Pointer zugreift. So etwas ist oft schwer zu finden.
|
AW: Schutzverletzung bei Zugriff auf Objekt
Insbesondere wenn mehrere Variablen das selbe Objekt referenzieren können, bei der Freigabe aufpassen.
Warnungen im Compiler einschalten, insbesondere eventuell nicht initialisierte Variablen. Allgemein Objekt.Free durch FreeAndNil(Objekt) ersetzen. Einen Breakpoint im Konstruktor und Destruktor der betreffenden Klasse setzen. Jeder Instanz eine fortlaufende Nummer geben und die Erzeugung, Freigabe und Zuweisung auf die Variable(n) an der Fehlerstelle protokollieren. |
AW: Schutzverletzung bei Zugriff auf Objekt
Danke schon mal für die Antworten. Das Komische ist, dass ich knapp vorher noch auf das Objekt zugreifen kann.
Delphi-Quellcode:
In der main Form kann ich auf das Objekt B zugreifen. Ich schreib Werte rein, und kann - wenn ich Breakpoints setze - auch das Objekt und seine Werte sehen. Und dann kommt eine simple Abfrage, die entscheidet, ob Prozedur X oder Prozedur Y ausgeführt wird. Wenn X ausgeführt wird, dann existiert das Objekt, ich kann via Breakpoint das Objekt und seine Werte einsehen, wenn Y ausgeführt wird, scheint das Objekt wie verschwunden, aber eben auch nicht NIL.
//main form
objekta.objektb.value_a := 123.0; if somecondition then objekta.prozedurx else objekta.prozedury; //TKlasseA procedure TKlasseA.prozedurx; begin objektb.value_b := 456; //geht end; procedure TKlasseA.prozedury; begin objektb.value_b := 456; //geht nicht end; Objekt B wird übrigens erst im destructor von Objekt A mit FreeAndNil freigegeben. Da komme ich aber nie hin. Und wie erwähnt, wenn ich genau das gleiche in einem neuen Testprojekte mache, dann funktioniert es auch. Es muss offenbar irgendeine merkwürdige Quer-Abhängigkeit sein. Das Objekt A wird auch nur ein mal erzeugt, nämlich im Create des Forms. Von der KlasseB werden allerdings in drei weiteren anderen Klassen Instanzen erzeugt. Kann da der Hund begraben liegen? Ist es entscheidend, wie ich die Klasse B in verschiedenen anderen Klassen instanziere? Das muss doch egal sein, oder? Danke jedenfalls für Eure Aufmerksamkeit! |
AW: Schutzverletzung bei Zugriff auf Objekt
Kann es denn sein, dass Du in dem Objekt irgendwas mit dem Speicher anstellst (getmem/freemem, dynamische Arrayzuweisungen, Pointerzugriffe etc.) und du damit vielleicht was im Speicher versehentlich überschreibst, das würde erklären warum ein "leeres" Projekt geht und dein anderes nicht?
|
AW: Schutzverletzung bei Zugriff auf Objekt
mit der Instanz der KlasseB mache ich sonst nichts dergleichen. Auch sonst im Projekt, in anderen Instanzen dieses Objekts habe ich keine Pointer, getmen/freemem, ...).
Was ich probiert habe, den Inhalt der ProzedureX nach Y zu kopieren. Das klappt auch nicht. Selbst wenn die ProzedurY genau den gleichen Inhalt hat, gibts die Schutzverletzung. So, als ob beim Aufruf dieser Prozedur das Objekt verschwindet. Hab auch mal eine neue Prozedur angegelegt (KlasseA.ProzedurZ) und den Inhalt von Y reinkopiert. Geht auch nicht. Ich könnte mal testweise alle anderen Instanzen von KlasseB weglassen. Aber dann funktioniert das Projekt de facto nicht mehr, da müsste ich praktisch alles auskommentieren, was das Ding macht. |
AW: Schutzverletzung bei Zugriff auf Objekt
Ist eine der Methoden X,Y,Z virtuell?
Das würde darauf hindeuten das die Variable "objekta" nicht auf eine gültige Instanze der Klasse TKlasseA verweist. Da der Fehler nur in deinem Projekt auftritt, lässt sich die Ursache auch nur im konkreten Code eingrenzen. Ohne Quellcode, mit dem man den Fehler reproduzieren kann, sind nur allgemeine Hinweise möglich. Bei dem geposteten abstrakten Code fehlen einfach zu viele Details. |
AW: Schutzverletzung bei Zugriff auf Objekt
Wenn du Zugriffsverletzungen in Methoden hast und den Fehler nicht finden kannst ist folgender Trick empfehlenswert:
Delphi-Quellcode:
In den Projektoptionen müssen die Asserts eingeschaltet sein.
procedure TKlasseA.prozedury;
begin Assert(Assigned(self)); // Sicherheitsprüfung Assert(Assigned(objektb)); // 2. Sicherheitsprüfung objektb.value_b := 456; //geht nicht end; Durch
Delphi-Quellcode:
wird sichergestellt, dass das Objekt in dem man aktuell arbeitet auch angelegt ist.
Assert(Assigned(self))
Wird die Assertion ausgelöst, bekommt du die Unit und die Zeilennummer an dem das Problem entdeckt wurde. |
AW: Schutzverletzung bei Zugriff auf Objekt
So einen ähnlichen "Fehler" hatte ich vor kurzem auch gehabt. Es gab keinen logischen Zusammenhang zwischen den Zugriffsverletzungen und dem dazu führendem Call-Stack. Die Ursache war im Grunde so alt wie C (und alle anderen Sprachen, die Pointer unterstützen), eine Bereichsüberschreitung beim variablen Array/manuell angefordertem Buffer.
Auf die Schliche kannst dem Fehler kommen, wenn du in den Compiler-Optionen die Option Bereichüberprüfung (am besten für das Debug-Build) aktivierst. Wenn du dann zur Laufzeit ERangeError-Exceptions bekommst, so ist meine Vermutung bestätigt. Aber Vorsicht, diese Compiler-Option vergrößert und verlangsamt die Anwendung, aber für's Debugging manchmal unerlässlich. MfG |
AW: Schutzverletzung bei Zugriff auf Objekt
Liste der Anhänge anzeigen (Anzahl: 1)
Hallo,
danke nochmals für den Input. Habe sowohl den Assert/Assigned-Trick versucht als auch die Bereichsüberprüfung. Es läuft aber letztlich offenbar immer darauf hinaus, dass dieses ObjektB im Objekt A nicht existiert. Freigegeben wird es aber auch nicht. Die Fehlermeldung anbei bringt wohl auch nicht mehr Licht in die Sache. |
AW: Schutzverletzung bei Zugriff auf Objekt
Aus der Fehlermeldung lässt sich folgendes schließen:
Du befindest dich in der Methode einer Klasse. Diese Instanze der Klasse wurde nicht erzeugt und die Instanzevariable ist "nil". Die Methode ist nicht virtuell, sonst wärst du nicht so weit gekommen. Zitat:
Zitat:
Wird das Property "objektb" eventuell mehrmals in unterschiedlichen Ebenen der Klassenhierarchie deklariert? Handelt es sich um eine einfache Variable oder wird das Objekt von einer Methode geliefert? Hast du die von mir vorgeschlagene Protokollierung der Erzeugung, Zuweisung, Freigabe der Klassen (objecta, objectb) mit Instanznummer implementiert? Zeig uns bitte das Protokoll. |
AW: Schutzverletzung bei Zugriff auf Objekt
Also, die Tipps hab ich natürlich befolgt und probiert (einzige Einschränkung: soweit ich sie auch verstanden habe - welches Protokoll etwa meinst Du? :oops: oder Instanznummer?).
Objekt A existiert, ich kann einen Breakpoint vor dem Aufruf der ProzedurY setzen und kann da alle Werte im ObjektA aber auch im Unterobjekt B einsehen. Objekt A und Objekt B existieren eine Codezeile vorher noch. Sobald ich eine Zeile später in die ProzedurY springe, scheint das Objekt B verloren zu sein. Was allerdings auch merkwürdig ist: dem Objekt A hab ich testweise noch ein paar Variablen hinzugefügt. Wenn ich nun in ProzedurY diese Variablen ansehe, so haben die zum Teil einen Inhalt, obwohl diesen Variablen nirgends ein Wert zugewiesen wurde. Noch merkwürdiger: der Inhalt macht Sinn, also die Werte, die da drinstehen, die kommen an anderer Stelle im Programm vor. Das sind die Inhalte anderer Variablen einer weiteren Instanz von ObjektB. Danke jedenfalls für die Mühe, da immer noch mitzulesen und zu helfen! |
AW: Schutzverletzung bei Zugriff auf Objekt
Kleines Update:
An den Objekten A und B selbst liegt es offenbar nicht, sondern es gibt eine Querabhängigkeit zu einem ObjektC (das auch eine Instanz vom ObjektB enthält). Genauer gesagt scheint es am SetLength von ein paar dynamischen Arrays im ObjektC zu liegen. Sobald ich die rausnehme, klappt es (natürlich fehlt dann ein großer Teil vom ObjektC). Wirklich schlau bin ich damit auch noch nicht. Das sollte jetzt vermutlich in einen neuen Thread, aber ich lasse es mal hier, da es Teil des Codes von ObjC ist: wenn ich ein dynamisches Array mehrmals in seiner Größe ändern muss, was ist dann der korrekte Weg: SetLength(analysis,0); SetLength(analysis,anzahl); oder nur SetLength(analysis,anzahl); Beeinflusst das den Speicherverbrauch bzw. die Entscheidung, was Delphi mit den alten Daten macht? |
AW: Schutzverletzung bei Zugriff auf Objekt
ps. wenn ich die Arrays konstant definiere [0..100] dann gibt es nirgendwo Fehlermeldungen ...
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:03 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