Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi EAccessViolation bei Free() (https://www.delphipraxis.net/35152-eaccessviolation-bei-free.html)

hitzi 3. Dez 2004 09:59


EAccessViolation bei Free()
 
Hallo,

hat jemand eine Idee warum bei folgenden Codestück ein EAccessViolation Fehler kommt?
Delphi-Quellcode:
destructor TMobilePIM.Free;
begin
  fTimer.Enabled := false;
  if assigned(FTimer) then FreeAndNil(fTimer);
  inherited Free(); //Hier kommt der Fehler
end;
Ab und zu kommt auch " ... raised too many consecutive exceptions ...". Ausgeführt mit Delphi 2005 Architect Trial.

Gruss

jim_raynor 3. Dez 2004 10:03

Re: EAccessViolation bei Free()
 
Mmh. Als Destructor wird Destroy verwendet und nicht free. Durch Free wird Destroy explizit aufgerufen. Es müsste also so aussehen:

Delphi-Quellcode:
destructor TMobilePIM.Destroy;
begin
  fTimer.Enabled := false;
  if assigned(FTimer) then FreeAndNil(fTimer);
  inherited;
end;
[Edit]Weiss nicht genau wie das bei Delphi 2005 ist, sollte aber bei einer Win32 Anwendung genauso sein.[/edit]

hitzi 3. Dez 2004 10:09

Re: EAccessViolation bei Free()
 
Ich hab's mal geändert. Jetzt wird allerdings dieser Destructor nicht mehr aufgerufen.

Hier die Procedure, welche das einleitet:
Delphi-Quellcode:
procedure TfrmContactDetails.FormDestroy(Sender: TObject);
begin
  if Assigned(fPim) then //fPim = TMobilePIM
  begin
    fPim.OnRefreshData := nil;
    fPim.Free;
    fPim := nil;
  end;
end;
und die geänderte Version:
Delphi-Quellcode:
destructor TMobilePIM.Destroy;
begin
  fTimer.Enabled := false;
  if assigned(FTimer) then FreeAndNil(fTimer);
  inherited Free();
end;
und die Deklaration unter Public:

Delphi-Quellcode:
destructor Destroy();reintroduce;
Auch wenn ich FreeAndNil(fPim) aufrufe, wird TMobilePim.Destroy nicht aufgerufen (jedenfalls nicht beim Schritt für Schritt Debuging.

Mario 3. Dez 2004 10:09

Re: EAccessViolation bei Free()
 
Den Timer erst zu Disablen und dann nach Prüfung freizugeben, ist teilweise sinnfrei. Wenn der Timer disabled werden kann, muss er auch existieren, dann kann die Prüfung mit Assigned danach einfach entfallen.

hitzi 3. Dez 2004 10:12

Re: EAccessViolation bei Free()
 
Ok Mario, hab's so geändert:

Delphi-Quellcode:
destructor TMobilePIM.Destroy;
begin
  if assigned(FTimer) then
  begin
    fTimer.Enabled := false;
    FreeAndNil(fTimer);
  end;
  inherited Free();
end;
Was passiert eigentlich, wenn das OnTimer Ereignis aufgerufen wird und genau in dem Moment der Timer freigegeben wird?

hitzi 3. Dez 2004 10:15

Re: EAccessViolation bei Free()
 
Zitat:

Zitat von jim_raynor
Weiss nicht genau wie das bei Delphi 2005 ist, sollte aber bei einer Win32 Anwendung genauso sein.

Es ist eine Win32 Anwendung.

teebee 3. Dez 2004 10:24

Re: EAccessViolation bei Free()
 
Mit dem 'reintroduce' verdeckst Du das Vorgänger-Destroy, es muss 'override' heissen. Ausserdem nur 'inherited;' und nicht 'inherited free;'.

In einer Single-Thread-Anwendung kann es nicht passieren, dass der Timer zerstört wird, während OnTimer aufgerufen wird. (Solltest Du natürlich auch nicht durch einen Aufruf im OnTimer provozieren.) Es reicht also, den Timer nur freizugeben.

Gruß, teebee

hitzi 3. Dez 2004 10:27

Re: EAccessViolation bei Free()
 
Mit folgender Procedure funktionierst:

Delphi-Quellcode:
procedure TMobilePIM.Free;
begin
  if assigned(FTimer) then
  begin
    fTimer.Enabled := false;
    FreeAndNil(fTimer);
  end;
  inherited Free();
end;
So aufgerufen:
Delphi-Quellcode:
procedure TfrmContactDetails.FormDestroy(Sender: TObject);
begin
  if Assigned(fPim) then //fPim = TMobilePIM
  begin
    fPim.OnRefreshData := nil;
    fPim.Free;
    fPim := nil;
  end;
end;
Eine letzte Frage dazu. fPim.Free und fPim := nil funktionieren ja - wieso funktioniert FreeAndNil(fPim) nicht? Bei FreeAndNil wird nicht! die Procedure TMobilePIM.Free aufgerufen.

MaBuSE 3. Dez 2004 10:53

Re: EAccessViolation bei Free()
 
Zitat:

Zitat von hitzi
Eine letzte Frage dazu. fPim.Free und fPim := nil funktionieren ja - wieso funktioniert FreeAndNil(fPim) nicht? Bei FreeAndNil wird nicht! die Procedure TMobilePIM.Free aufgerufen.

Das sollte eigentlich funktionieren.

FreeAndNil ist in der SysUtils enthalten und hat folgenden Quelltext:
Delphi-Quellcode:
...
{ Copyright (c) 1995-2002 Borland Softwrare Corporation                  }
...
unit SysUtils;
...
procedure FreeAndNil(var Obj);
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;
...
Es wird also die Free Methode des Objektes aufgerufen. :gruebel:

hitzi 3. Dez 2004 11:04

Re: EAccessViolation bei Free()
 
Wird's aber nicht :(

Wieso wird das eigentlich so von Borland gelöst.
Wäre ein
Delphi-Quellcode:
Obj.Free;
Obj := nil;
nicht kürzer und schneller?


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:27 Uhr.
Seite 1 von 2  1 2      

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