![]() |
Zugriffsverletzung bei Adresse 00000000 bei TImage
Hallo,
ich brauche mal wieder eure Hilfe. Ich habe hier eine hübsche Zugriffsverletzung bei Adresse 00000000 'Lesen von Adresse 00000000' wenn ich im Code einer Klasse auf ein klasseneigenes TImage-Objekt zugreifen möchte. Also so ungefähr:
Delphi-Quellcode:
Normalerweise würde man sagen "Ganz klar, kein Objekt instanziert", aber:
TKlasse = class
private Bild: TImage; public procedure MachWas; end; //... procedure TKlasse.MachWas; begin //... Bild.Left := 20; //Hier rührt der Fehler her //... end;
Delphi-Quellcode:
Jetzt kommt's aber noch doller:
constructor TKlasse.Create(AOwner: TComponent);
begin //... Bild := TImage.Create; //... end; Wenn ich genau das gleiche, was ich mit diesem TImage-Objekt mache, mit einem anderen - nennen wir es Bild2 - mache, dann kommt kein Fehler. Und mit genau das gleiche meine ich ALLES gleich machen, d.h. cocy & paste bei allen Sachen für Bild im Code und auf Bild2 geändert. Jetzt weis ich nicht mehr, wo ich noch nach dem Fehler suchen soll... Wenn ich die Stelle oben auskommentiere, gibts keinen Fehler mehr. Umbenennen des ersten TImage-Objekts auf irgendwas anderes bringt auch nix. Ach ja - vllt. ist das noch wichtig: Die Fehlermeldung erscheint, wenn man die Form schließt und dann zeigt Delphi das CPU-Fenster... Vielleicht könnt ihr mir ja einen Tipp geben, wo ich da mal ansetzen könnte zu suchen, da ich leider nicht den ganzen Code posten kann... Gruß und Danke im Voraus Seb |
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Existiert den eine Instanz von TKlasse?
|
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Wenn du irgendwo eine AV bei Zugriff auf $00000000 erhältst, ist das meißstens ein Zugriff auf einen Pointer, der nil ist, bzw. auf einen Klassenzeiger, der nil ist, in diesem Fall ist dieser Pointer, der nil ist, wahrscheinlich self, du hast also vergessen, die Klasse zu erzeugen.
|
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Darf ich zitieren:
Zitat:
|
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Hast Du evtl. 2 mal
Delphi-Quellcode:
im Source Deiner Klasse?
Bild.Free;
|
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Hier sihet man nur, das eine Instanz für den Member Bild erzeugt wird. nicht aber für die Klasse TKlasse.
|
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Nicht ob das Bild instantiiert ist, ob deine TKlasse instantiiert ist.
|
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
nein, nur einmal im destructor.
Das Seltsame ist ja auch, dass der Code theoretisch funktionieren müsste, bei dem einen auch praktisch funzt aber bei einem auch wieder nicht! :coder2: Edit: Ja, ist sie. Kann ich garantieren. Denn sonst würde der Rest auch nicht laufen (is n bisssschen größer die Klasse als nur das oben) und ich weis auch, dass ichs selbst eingebaut hab. Kurz gesagt: Ja, bin zu 100% sicher. |
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Du hast aber TImage nicht neu deklariert? Ansonsten stimmt der Aufruf dessen Konstruktors nicht, da hier ein Parameter vom Typ TObject TComponent erwartet wird.
[edit] Parametertyp korrigiert [/edit] |
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Geh mal mit Breakpoint bis an die Stelle, wo der Fehler auftritt, und prüfe mit dem Evaluator den Wert von Self und von deinem Bild.
|
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
@DeddyH: O, stimmt. Tut mir Leid, hab oben das falsch geschrieben. Ist natürlich im Original-Code richtig mit Parameter.
@3_of_8: Bin dran... |
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
muß man TImage nicht beim .Create einen Owner übergeben?
Zitat:
|
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
@3_of_8: Also, bin jetzt Zeile für Zeile durchgesprungen - läuft ohne Probleme. Der Fehler tritt erst auf, wenn man die Form schließt.
@himitsu: Also den AOwner habe ich durchgeschleift, d.h. das ist der des Klassen-Konstructors. Wahrscheinlich liegt hier der Hase im Pfeffer. Beim Erzeugen eines Objekts hatte ich dem Constructor schon mal Application mitgegeben, dann auch mal den eigenen Objektnamen. Es machte bisher keinen Unterschied und funktionierte Einwandfrei - habe auch schon gegooglet, aber so richtig schlau geworden, wo der Unterschied liegt, bin ich nicht. Vielleicht sollte ich noch dazu sagen (jetzt werde ich wahrscheinlich gesteinigt), dass ich das Objekt unter initialization instanziere, denn wenn ich das erst bei FormCreate einbaue (habs mal getestet), kommt ein schöner Fehler. |
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Dann zeig doch mal die relevanten Quellcode-Stellen, bevor wir hier weiter in einer Blackbox herumstochern.
|
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Gibst du das Bild auch wieder irgendwann frei?
|
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Nur im Destruktor, hat er weiter oben gesagt.
|
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
@ 3_of_8:
Zitat:
@DeddyH: bitteschön:
Delphi-Quellcode:
initialization
Klasse := TKlasse.Create(Klasse); //Ob das wohl so stimmt??? end.
Delphi-Quellcode:
//Klassendefinition habt ihr ja schon oben
constructor TKlasse.Create(AOwner: TComponent); var begin inherited Create(AOwner); Bild := TImage.Create(AOwner); with Bild do begin Parent := Self; Transparent := true; //usw. - alles, was man hier tun will, geht, ohne dass es beim Schließen einen Fehler erzeugt end; end; destructor TKlasse.Destroy; begin Bild.Free; //da wirds gekillt end; Wenn ich jetzt in irgendwelche "hauseigenen" Prozeduren (z.B. wie oben procedure TKlasse.MachWas;) z.B. Bild.Top := 5; reinschreibe, dann gibts beim Schließen n Fehler Was mich ja am Meisten fuchst, ist, dass - wenn ich die Passage aus der Prozedur rausnehme - sowohl "Bild" als auch das andere TImage-Objekt funktioniert |
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Okay. Du übergibst also dem Image einen Owner und gibst das Image frei, wenn deine Klasse freigegeben wird. Jetzt wird der Owner selbst freigegeben und hat noch das Image, um das er sich ja kümmern soll, und versucht es freizugeben. Was passiert, wenn man ein bereits freigegebenes Objekt nochmal freigeben will? Richtig, es kracht. :mrgreen:
Also: Übergib nil als Owner. |
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Danke für deine Antwort.
Habe jetzt folgendes im Konstruktor stehn:
Delphi-Quellcode:
...aber es kracht immer noch. Diemal sagt er (mal etwas konkreter): Exception der Klasse EInvalidPointer Meldung: "Ungültige Zeigeroperation"
//...
Bild := TImage.Create(nil); //... Hmmm... Mist. Was nu? :glaskugel: |
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Hast du mal durch schrittweises Ausführen im Debugger versucht herauszufinden in welcher Zeile der Fehler auftritt?
|
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Zitat:
Mach ambesten folgendes: * Breakpoint bei der Position wo der Fehler kommt * Breakpoint im Destroy von der Klasse So nun schliesst du deine Exe und springst solange weiter bis du im Destroy angekommen bist. Wird der andere Breakpoint danach noch aufgerufen? |
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Hurra, erster Erfolg: Er kommt tatsächlich noch mal da vorbei. Abver mir ist sehr schleierhaft, wo der Aufruf herkommen soll...
Die Prozedur, in der er vorbeikommt und wo der Fehler auftaucht wird nur bei einer Größenänderung (OnResize) und im Constructor aufgerufen... :gruebel: Edit: Nachtrag: Wenn ich das Bild.Free; aus dem Destructor rausnehme, gehts logischerweise. Aber das ist dann ja nicht mehr saubere OOP, oder? |
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Naja, ist im Prinzip auch egal, wenn das Programm beendet ist, wird der Speicher sowieso freigegeben. Aber ich frag mich auch, wieso das noch kracht - irgendwas ruft offenbar noch den Destruktor von dem Bild auf, aber wenn du keinen Owner übergibst, wer könnte das denn dann noch sein?
|
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Zitat:
Gebe deine Klasse nicht mit Bild.Free sondern mit FreeAndNil(Bild) frei. Dann versiehst du jeden Aufruf von Bild mit:
Delphi-Quellcode:
if Bild <> nil then Bild.Irgendwas;
|
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Deshalb auch meine Frage aus
![]() |
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Selbst die Krücke geht nicht...
bin so langsam am verzweifeln.... |
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Jetzt prüf doch nochmal alles durch, ob
- die Klasse in jedem Fall erzeugt und - sie nicht vor dem Aufruf des Destruktors freigegeben wird |
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Mal eine (blöde) Frage, um was für ein Bild handelt es sich denn ( JPEG ) ?
Ich frage deswegen: ungefähres Zitat ... Wenn ich das mit einem anderem Bild mache, klappt es ... |
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Zitat:
aber wenn das auch "Klasse" ist, dann liegt da vermutlich wirklich das Problem. PS: [TImage].Left greift auf dessen Owner zu ... drumm sollte da besser mal alles korrekt ablaufen!
Code:
und hier ... welchen Wert hat Klasse denn vorher?
[b]initialization[/b]
[color=#ff0000]Klasse[/color] := TKlasse.Create([color=#0000ff]Klasse[/color]); //Ob das wohl so stimmt??? [b]end[/b]. ich vermute aber mal, daß Klasse irgendwo als eine globale Variable definiert ist, weswegen sie wohl zufällig den wert NIL enthält und warum es rein zufällt, bei diesem Aufruf nicht kracht. ([TImage].Create greift auch auf den Owner zu, wenn er existiert, also nicht NIL ist) ja und Klasse is nicht Klasse ... es sind 2 unterschiedliche Inhalte. |
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Also: 1. Ich arbeite da mit leeren Bildern, da ich nur die Hover- und OnClick- Eigenschaften brauche. Wenn dafür jemand ne bessere Idee hat, dann könnte ich das Ganze komplett umgehen.
Also sollte ich beim Create besser
Delphi-Quellcode:
schreiben, oder wie sonst?
Klasse := TKlasse.Create(Application);
|
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
Ja oder Nil.
|
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
da hätte ja, statt TImage eine TPaintBox auch ausgereicht.
Was und vorallem wo willst du denn genau erreichen? Wenn du z.B. auf einer Form einen sensitiven Bereich haben möchtest, dann reicht es auch OnMouseMove und OnMouseDown der Form zu erweitern und dort abhängig von der MousePosition zu reagieren. |
Re: Zugriffsverletzung bei Adresse 00000000 bei TImage
So - habe es jetzt wieder gemacht, wie ichs vorher hatte. D.h. so wie im Post über diesem beschrieben. Das Problem bei der Art war, dass es beim Hovern geblinkt hat wie bescheuert. Die Lösung (eigentlich total simpel): es wurde zu oft neugezeichnet. Ne boolsche Variable her und gut war.
Trotzdem nochmal ganz herzlichen Dank an alle, die sich hier durch ihr Fachwissen ausgezeichnet und mir geholfen haben. Gruß Seb :hello: |
Alle Zeitangaben in WEZ +1. Es ist jetzt 23:22 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