Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Zugriffsverletzung bei free? (https://www.delphipraxis.net/87694-zugriffsverletzung-bei-free.html)

Hyperspacer 4. Mär 2007 19:07


Zugriffsverletzung bei free?
 
Ich beiß gleich in die tischkante.. :wall:

Ich erstelle dynamisch ein Tedit, dem ich zwei ereignisproceduren zuweise:
Delphi-Quellcode:
with TEdit.Create(form1) do
  begin
    Parent := Form1;
    Top := 50;
    Left := 100;

    SetFocus;

    OnExit := ItemEditOnExit;
    OnKeyDown := ItemEditOnKeyDown;
  end;
So weit so gut. Hier nun die Proceduren:
Delphi-Quellcode:
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;
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.
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

Neutral General 4. Mär 2007 19:21

Re: Zugriffsverletzung bei free?
 
Delphi-Quellcode:
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;
Schreib das mal so.. Is nur son Gefühl...
Keine Garantie!

Gruß
Neutral General

SirThornberry 4. Mär 2007 19:29

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

Hyperspacer 4. Mär 2007 19:41

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:

TonyR 4. Mär 2007 20:39

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:

Hyperspacer 4. Mär 2007 20:51

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

SirTwist 4. Mär 2007 22:15

Re: Zugriffsverletzung bei free?
 
Zitat:

Zitat von Hyperspacer
... Obowhl ich den fehler schon komisch finde

Mit diesem Code hier:
Delphi-Quellcode:
with TEdit.Create(form1) do begin
  ...
end;
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.

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:
  tmp_edit := TEdit.Create(form1);
  with tmp_edit do begin
    tmp_edit.Parent := form1;
  end;
und dann spätestens im FormClose-Event:
Delphi-Quellcode:
  FreeAndNil(tmp_edit);

Christian Seehase 4. Mär 2007 22:21

Re: Zugriffsverletzung bei free?
 
Moin Daniel,

nur um das

Zitat:

Zitat von Hyperspacer
Wenn ich jetzt erneut ein Edit erstelle, etwas hineinschreibe und "enter" drücke gibt es KEINEN fehler!

mal zu klären.

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.

xaromz 4. Mär 2007 22:25

Re: Zugriffsverletzung bei free?
 
Hallo,

nur um das geradezurücken:
Zitat:

Zitat von SirTwist
Mit diesem Code hier:
Delphi-Quellcode:
with TEdit.Create(form1) do begin
  ...
end;
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.

Diese Aussage ist natürlich Blödsinn. Das Objekt wird nicht freigegeben (Delphi-Klassen besitzen keine Referenzzählung und Delphi hat auch keinen GC). Es existiert nur keine Variable, mit der das Objekt angesprochen werden kann.

Gruß
xaromz

TStringlist 4. Mär 2007 23:57

Re: Zugriffsverletzung bei free?
 
edit: stand schon irgendwo


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:02 Uhr.
Seite 1 von 2  1 2      

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz