![]() |
Zugriffsverletzung bei free?
Ich beiß gleich in die tischkante.. :wall:
Ich erstelle dynamisch ein Tedit, dem ich zwei ereignisproceduren zuweise:
Delphi-Quellcode:
So weit so gut. Hier nun die Proceduren:
with TEdit.Create(form1) do
begin Parent := Form1; Top := 50; Left := 100; SetFocus; OnExit := ItemEditOnExit; OnKeyDown := ItemEditOnKeyDown; end;
Delphi-Quellcode:
Wenn die OnExit Procedure ausgeführt wird, geht alles glatt. Aber wenn die OnKeyDown Procedure ausgeführt wird gibt es eine wunderschöne Zugriffsverletzung nachdem Free.
procedure TForm1.ItemEditOnExit(Sender: TObject);
begin ListView1.ItemFocused.SubItems.Strings[0] := (Sender as TEdit).Text; Sender.Free; end; procedure Tform1.ItemEditOnKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState); begin If Key = VK_Return then begin ListView1.ItemFocused.SubItems.Strings[0] := (Sender as TEdit).Text; Sender.Free; end; end; Ich habe schon versucht das Edit nicht in der OnKeyDown Procedure zu freen, sondern von dort die OnExit Procedure auszuführen, was allerdings zum selben Fehler führte. Wer kann mir sagen wie ich diesen Fehler beheben oder umschippern kann? mfg Daniel |
Re: Zugriffsverletzung bei free?
Delphi-Quellcode:
Schreib das mal so.. Is nur son Gefühl...
procedure Tform1.ItemEditOnKeyDown(Sender: TObject; var Key: Word; Shift: TShiftState);
begin If Key = VK_Return then begin ListView1.ItemFocused.SubItems.Strings[0] := (Sender as TEdit).Text; TEdit(Sender).OnExit := nil; // <--- Sender.Free; end; end; Keine Garantie! Gruß Neutral General |
Re: Zugriffsverletzung bei free?
innerhalb eines Events sollte man NIE die Komponente frei geben denn das Event ist etwa so aufgebaut
Delphi-Quellcode:
//Wenn OnChange zugewiesen ist
if Assigned(OnChange) then OnChange(Self); //OnChange aufrufen Self.DoAnything; //Wenn jetzt die Componente im OnChange freigegeben wurde knallts weil Self ja nicht mehr auf was gültiges zeigt sondern frei gegeben wurde |
Re: Zugriffsverletzung bei free?
Danke für die schnellen Antworten!
@SirThornberry: Klingt logisch aber da gibt es nochetwas. Ich erstelle das Edit zum ersten mal. Dann schreibe ich irgendetwas hinein und drücke "Enter". Peng Fehler. Das Edit ist nach dem Fehler wenigstens nicht mehr zu sehen, ob es auch wirklich weg ist kann ich nichtsagen. Der Text wurde erfolgreich in die Liste geschrieben. Wenn ich jetzt erneut ein Edit erstelle, etwas hineinschreibe und "enter" drücke gibt es KEINEN fehler! Jetzt bin ich völlig verwirrt. :coder2: Edit: Überigens herzlichen Glückwunsch zum 6.666sten Beitrag :thumb: |
Re: Zugriffsverletzung bei free?
Ich weis ja nicht, was du vor hast, aber wäre es nicht auch eine Idee, das Edit im Designer oder von mir aus im Oncreate zu erstellen und es erst beim schließen des Progs wieder Freizugeben???
Um es zwischenzeitlich unsichtbar zu machen, kann man ja Hide benutzen :gruebel: |
Re: Zugriffsverletzung bei free?
Manchmal sind die Antworten so einfach! :mrgreen:
Nur der Vollständigkeit halber: Ich habe ein Listview und will auch die subitems direkt editieren können. dafür hatte ich vor (was auch soweit funktioniert) bei einem doppelklick auf einen bestimmten eintrag im listview ein editfeld an dieser stelle zu erstellen mit dem man dann den eintrag bearbeiten kann. Aber man kann ja auf einfach eins von anfang an erstellen, unsichtbar machen und dann immer an die richtige stelle verschieben und sihtbar machen... okay danke an euch alle! ... Obowhl ich den fehler schon komisch finde mfg Daniel |
Re: Zugriffsverletzung bei free?
Zitat:
Delphi-Quellcode:
legst Du zwar ein TEdit an und initialisierst du es, aber direkt nach dem End wird es wieder freigegeben, weil du es keiner Variablen zuweist. Und damit arbeiten all deine Routinen, die du zuweist, im luftleeren Raum, und dein Sender.Free gibt bereits freien Speicher nochmal frei.
with TEdit.Create(form1) do begin
... end; Wenn Du schon Controls on-the-fly erzeugen willst, musst Du sie in einer Variable speichern, und zwar keiner lokalen innerhalb der Prozedur, sondern innerhalb der aktuellen Klasse/des aktuellen Forms:
Delphi-Quellcode:
und dann spätestens im FormClose-Event:
tmp_edit := TEdit.Create(form1);
with tmp_edit do begin tmp_edit.Parent := form1; end;
Delphi-Quellcode:
FreeAndNil(tmp_edit);
|
Re: Zugriffsverletzung bei free?
Moin Daniel,
nur um das Zitat:
Wenn Du das Free ausführst, wird der Speicher, den die Komponente belegt hat, zur erneuten Verwendung freigegeben. Je nach Konstellation kann es dabei auch vorkommen, das die Komponente dennoch so vollständig erhalten bleibt, das spätere Zugriffe darauf noch einwandfrei funktionieren, es kann aber auch sein, dass entscheidende Bereiche schon wieder überschrieben wurden => AV. Du kannst das vergleichen mit dem Löschen einer Datei. Wenn danach noch nicht viel auf der Platte geändert wurde, stehen die Chancen recht gut diese wiederherstellen zu können, es können aber auch schon Bereiche davon überschrieben worden sein. |
Re: Zugriffsverletzung bei free?
Hallo,
nur um das geradezurücken: Zitat:
Gruß xaromz |
Re: Zugriffsverletzung bei free?
edit: stand schon irgendwo
|
Re: Zugriffsverletzung bei free?
Zitat:
Zitat:
Da bei ihm Form1 der Owner vom Edit ist, ist das Edit über die Liste Form1.Components referenzierbar. Und weil Form1 der Parent vom Edit ist, ist das Edit ebenfalls in Form1.Controls greifbar. Dazu sollte allerdings sinnigerweise Edit.Name beim Createn belegt werden. Zitat:
Objekte vom Typ TComponent (bzw. dessen Ableitungen) zerstören die Komponenten, deren Owner sie sind, bei ihrer eigene Freigabe immer mit. |
Re: Zugriffsverletzung bei free?
Jepp, Ihr habt natürlich recht :-)
Daran, dass das Control durch die Zuweisung des Parents in die Control-Liste des Parents aufgenommen wird, habe ich wirklich nciht gedacht. Und dass ein Objekt einfach so im Raum stehen bleibt, auch ohne jede Referenzierung... nun, ich bin bislang immer vom Gegenteil ausgegangen, habe das gerade mal überprüft und Du hast natürlich recht. Das habe ich wohl von Perl falsch übernommen. |
Re: Zugriffsverletzung bei free?
Okay also das problem an sich hab ich jetzt mit einem unsichtbaren edit umgangen, das ich verschiebe und sichtbar mache wenn ich es benötige.
Aber der Grund des Fehlers ist mir immer noch nicht so ganz klar. Schließlich gibts es ihn ja nur bei einem der beiden Events... Also kann doch das hier in diesem fall nicht zutreffen: (oder???) [by SirThornberry] Zitat:
[by Christian Seehase] Zitat:
|
Re: Zugriffsverletzung bei free?
Moin Hyperspacer,
Zitat:
Davon, dass das Edit danach immer noch funktionsfähig ist war bislang nicht die Rede. So unmittelbar erklären, könnte ich das nicht. Wenn Du mir mal den kompletten Code mit dem sich das reproduzieren lässt zur Verfügung stellen kannst, könnte ich mal versuchen dem mit Hilfe der Debug-DCUs auf den Grund zu gehen. Die dürften bei Deiner Personal nicht dabei sein. |
Re: Zugriffsverletzung bei free?
Die sichtbaren Auswirkungen könnten "Zufall" sein!
Ich habe das Beispiel aus dem ersten Posting hier nachvollzogen. Das Edit wird bei mir mit einem Button-Click erzeugt. Ich bekomme immer eine Exception, egal beim wievielten erzeugenten Edit ich Enter drücke. Das Edit bleibt bei mir nie sichtbar, das Programm schmiert immer ab. Vermutung: Die OnExit Methode funktioniert nur ohne Fehler, weil sie in der ganzen Kette der OnExit-Ereignisbehandlung als letztes abgearbeitet wird und nicht zum Edit zurückkehren muss. Ich habe das jetzt nicht step-for-step nachvollzogen, aber ganz viel anders kann es (zumindest sinngemäß) nicht sein. Die OnKeyDown-Methode muss aber zum Edit zurückkehren, das es aber nach dem Free nicht mehr gibt --> Folge: Crash. Eigentlich ist es aber auch wurscht, wieso und weshalb ... Es ist und bleibt der alte Grundsatz: Objekte nie in einer eigenen Ereignisbehandlungsmethode freigeben! Grundsatz beachten und glücklich sein. :cyclops: ((Irgendwo steht hier oder im DF aber auch eine Umgehung, mit der man eine "Quasi-Selbstzerstörung" vornehmen kann.)) |
Re: Zugriffsverletzung bei free?
Nabend,
Zitat:
Zitat:
Nochmal danke an alle, die sich mit dem Problem befasst haben. :cheers: mfg Daniel |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:21 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