![]() |
Zugriffsverletzung bei Zugriff auf Objekt
Hallo,
ich erhalte eine Zugriffsverletzung, wenn ich auf eine Eigenschaft eines Objektes zugreifen möchte. Diese Eigenschaft ist vom Typ TObject deklariert. Der Absturz erfolgt bereits dann, wenn ich nur "xxx.Instance is TEineKlasse" versuche, auch bei "xxx.Instance.ClassName" stürzt es ab. Dabei zeigt der Debugger unmittelbar vor der Zugrffsverletzung an, daß die erste Bedingung nicht zutrifft (Typ also unbekannt). Lediglich die Prüfung "if xxx.Instance = nil" funktioniert, ist aber niemals wahr. Was kann ich tun? Wie dem Fehler überhaupt auf die Schliche kommen? Vielen Dank im voraus Winter |
Re: Zugriffsverletzung bei Zugriff auf Objekt
Wie sieht dein Code inklusive Deklaration denn genau aus?
|
Re: Zugriffsverletzung bei Zugriff auf Objekt
... und wieso greifst du auf ".Instance" zu? Was für ein Sinn liegt dahinter?
|
Re: Zugriffsverletzung bei Zugriff auf Objekt
Hallo,
das Objekt ist entweder nicht intialisiert oder wurde mit .Free freigegeben. Lokale Variablen werden nicht initialisiert, ein Test auf is NIL bringt also nichts.
Delphi-Quellcode:
Ist MyObject im TForm selber als Variable gesetzt,
procedure TForm1.Bla;
var MyObject: TObject; begin if MyObject=NIL then begin // wird nie aufgerufen end; if MyObject is TObject // crash end; ist es NIL. Heiko |
Re: Zugriffsverletzung bei Zugriff auf Objekt
Hallo,
wieso, weshalb, warum spielt hier doch keinerlei Rolle. Tatsache ist, der Code existiert so. Ich kann ihn nicht posten, weil es ein riesiges Projekt ist, und ich auch nicht weiß, wo dieser .Instance-Eigenschaft etwas zugewiesen wird (wo schon, aber da wird wieder ein Parameter übergeben, das ganze zigmal durchlaufen und nur einmal kommt ein Fehler). Also: ich habe bei der Erzeugung des Objektes, von dem .Instance eine Eigenschaft ist, diese initialisiert mit NIL. Guter Einwurf, ändert aber nichts. Nur um alles auszuschließen: die Abfrage mit "is nil" geht doch sowieso nicht, es muß doch "= nil" oder "Assigned()" heißen? Zur Veranschaulichung doch noch ein wenig Code: Bei der Deklaration der Row-Klasse:
Delphi-Quellcode:
In einer anderen Klasse dann:
public
Instance: TObject; Bei der Erzeugung: constructor TRow.Create; begin [...] Instance := NIL; end; if (not (Row.Instance is TclsAIArticleItem)) ... // Fehler Also: .Instance ist nicht NIL, ist aber auch kein Objekt der Klasse oder einer abgeleiteten Klasse, die abgefragt wird (deshalb der Compilerfehler), sondern es zeigt irgendwohin. Es wird aber auch offenbar nirgends ein Objekt einer anderen Klasse zugewiesen. Row.ClassName geht auch nicht! Verdammt! [edit=SirThornberry]Delphi-Tags gesetzt - Mfg, SirThornberry[/edit] |
Re: Zugriffsverletzung bei Zugriff auf Objekt
Delphi-Quellcode:
Und wo wurde Instance erzeugt? Und was willst du mit einer Instanz der Klasse TObject? TObject ist doch nur eine Basisklasse, die nichts kann, für eigene Klassen, damit man die Grundfunktionalität nicht selber implementieren muss.
constructor TRow.Create;
begin [...] Instance := NIL; end; |
Re: Zugriffsverletzung bei Zugriff auf Objekt
Ach so. Also, das .Instance wird in der Klasse, in der es definiert wird, tatsächlich nicht weiter bearbeitet, außer der Initialisierung auf Nil. Es ist nur eine Eigenschaft, die von der Klasse bereitgestellt wird. Da wird dann jeweils ein anderes Objekt drangehängt, also von der Klasse, die ein Objekt davon verwendet. Eben so wie im Code dargelegt (sorry, ich wußte nicht, daß wegen solchen Fragmenten sich die Code-Formatierung lohnt; dachte das zerstückelt alles).
Bevor der Fehler auftritt, ist bei der Debugger-Untersuchung nur die Abfrage auf die Klassenzugehörigkeit von TObject (Row.Instance is TObject) wahr, alles darunter falsch. Tja, es wird also nicht irgendwo (versteckt) zugewiesen, ist nicht nil, obwohl es mit nil initialisiert wurde. Hat jemand noch Ideen? Vielleicht irgendetwas, was nicht von TPersistent abstammt? |
Re: Zugriffsverletzung bei Zugriff auf Objekt
Zwei allgemeine Hinweise bzw. Hilfen:
- Klassenmember werden mit Nil, 0, false, 0.0, etc initialisiert. Eine Zuweisung von Nil im Constructor ist nicht nötig. - Eine Abfrage mit IS beachtet ein Nil Objekt und gibt dann false zurück. Man kann sich also folgendes verkürzen:
Delphi-Quellcode:
zu einem einfachen
If assigned(Object) and ( Object is TMyClass ) then
TMyClass(Object).Blubb;
Delphi-Quellcode:
Und nun noch was grundsätzliches: Folgendes steht doch fest:
if Object is TMyClass then
1. es wird mit NIL initialisiert. Es ist auch ordentlich nil. 2. während der Laufzeit wird irgendwann mal ein Objekt zugewiesen (es ist nicht mehr nil) 3. Es wird während der Laufzeit darauf zugegriffen und es ist nicht nil, aber der Zugriff schlägt fehl. Somit würde es bedeuten, das das Element freigegeben wurde aber die Referenz in Instance nicht aktualisiert (sprich: nil gesetzt) wurde. Lösung des Problems: Finden wo es gesetzt wird und dies objekt weiter verfolgen bzw. wo diese freigegeben wurde. Dabei würde ich entweder einen Brechpunkt auf Instance setzen und "bei Änderungen anhalten" wählen oder du definierst Instance als Property um und stellst einen Brechpunkt in den Setter. Wenn dieser auslöst, dann das zugewiesene Objekt ermitteln. Dann in den Destructor stellen und bei dem Brechpunkt die Bedingung einfügen, welche den Namen des Komponente oder den Klassennamen vergleicht (zur Not auch die Instanz selber). Wenn dieser dann auslöst, dann weiss man wo diese freigegeben wird (Aufruf Stack, STRG-ALT-S) und man kann sich nun fragen, warum dort vorher nicht das Instance Feld auf NIL gesetzt wurde. Und noch was zu meinem vorherigen Beitrag, auch wenn es eine pampige Antwort nach sich zog: hinter der "lockeren" Beschreibung mit Instance hatte ich eine Eigenschaft von TObject vermutet (ähnliche InstanceSize) und nicht eine eigene! Auch wenn es somit am Thema vorbei ging, aber es war nur gut geraten, schliesslich gab es keinen Quellcode und keine eindeutige Beschreibung die dies ausschliessen liess. Also 'tschuldigung, dass meine Glaskugel was falsches orakelt hatte... |
Fortgeschrittenes Debugging
Danke. Stimme soweit zu bezüglich der Fehler-Analyse. War nicht so pampig gemeint, wollte es nur übersichtlich halten.
Falls sich jemand frägt, warum durchsucht er denn nicht den Quelltext: es handelt sich mit der Row um eine zentrale Klasse, die ein selbst entworfenes Grid implementiert und die zigfach im ganzen Projekt verwendet wird. Genaugenommen ist noch eine Klasse drumherum die die Instance-Eigenschaft dann setzt, wie gesagt mit einem Wert (Objekt), der auch nur übergeben wird. Und der Aufruf dieser Methode findet sich natürlich auch 100.000 Mal. Leider gibt es auch viele Reihen, so daß beim Debugging alles entsprechend oft durchlaufen wird, was es zusätzlich unangenehm macht. Wie nutze ich die von Dir angesprochene Funktion "bei Änderungen anhalten?". Sowas wäre wirklich sehr nützlich. Wie läßt sich als Haltepunkt-Bedingung ein einzelnes Objekt unterscheiden? Wohl muß ich schauen, wie es sich der Übeltäter am besten identifizieren läßt. Ich mache das jetzt mal und melde mich dann wieder. |
Re: Zugriffsverletzung bei Zugriff auf Objekt
Du kannst dir die Objekt Eigenschaft "überwachen" lassen (STRG-F7: Auswerten/Ändern und dort kannst du ihn Überwachen lassen) oder auch direkt über Menu -> Ansicht -> Debug-Fentser -> Überwachte Ausdrücke. Dort gibt es dann bei dem eingetragenen Wert die Möglichkeit über Rechtsklick "bei Änderung anhalten" auszuwählen.
Und zur Identifizierung der Objekte eignen sich die Namen, ClassName, bestimmte Eigenschaftswerte oder einfach nur die Instanzenadresse selber. Grundsätzlich kannst du im Haltepunkt-Eigenschaftsdialog (Rechtsklick auf den Haltpunkt, dort dann Haltepunkt-Eigenschaften) Bedingungen oder auch Durchlaufzähler festlegen. U.a. kannst du bei den Bedingungen ja sagen, dass der Name des Objektes ein bestimmter sein soll. Die Bedingunen in der Zeile kannst du frei festlegen ( z.B. Instance.Name = 'Label14' ). |
Alle Zeitangaben in WEZ +1. Es ist jetzt 07:20 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