Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Sonstige Fragen zu Delphi (https://www.delphipraxis.net/19-sonstige-fragen-zu-delphi/)
-   -   Delphi <Variable> möglicherweise nicht initialisiert (https://www.delphipraxis.net/143973-variable-moeglicherweise-nicht-initialisiert.html)

ToFaceTeKilla 27. Nov 2009 08:47


<Variable> möglicherweise nicht initialisiert
 
Hiho,
ich bin grad am Bereinigen der Warnmeldungen in meinem Projekt und wollte mich jetzt mal der Meldung
"[Warnung] Unit.pas(178): Variable 'aFStream' ist möglicherweise nicht initialisiert worden" annehmen.
Delphi-Quellcode:
try
  FFilePath:= dlgOpenSQL.FileName;
  aFStream:= TFileStream.Create(FFilePath,fmOpenRead);
  lblFile.Caption:= dlgOpenSQL.FileName;
  btnProtocol.Enabled:= True;
except
  on e: Exception do
    begin
      MessageDlg('Fehler beim Laden der Datei!'#13#10+e.Message,mtError,[mbOk],0);
      aFStream.Free;
    end;
end;
Nun könnte ich natürlich die Pfadzuweisung und das Create vor das try verlagern, aber würde das nicht den ganzen Sinn des try..except-Blockes aufheben? Den hab ich ja gerade wegen der Dateioperation geschrieben... :gruebel:

DeddyH 27. Nov 2009 08:54

Re: <Variable> möglicherweise nicht initialisiert
 
Delphi-Quellcode:
try
  FFilePath:= dlgOpenSQL.FileName;
  aFStream:= TFileStream.Create(FFilePath,fmOpenRead);
  try
    lblFile.Caption:= dlgOpenSQL.FileName;
    btnProtocol.Enabled:= True;
  finally
    aFStream.Free;
  end;
except
  on e: Exception do
    begin
      MessageDlg('Fehler beim Laden der Datei!'#13#10+e.Message,mtError,[mbOk],0);
    end;
end;
Oder soll der Stream nur im Fehlerfall freigegeben werden?

SirThornberry 27. Nov 2009 09:00

Re: <Variable> möglicherweise nicht initialisiert
 
Die Warnmeldung würdest du auch weg bekommen wenn du vor dem Try-Except-Block die Variable auf nil setzt. Ansonsten ist die Meldung schon berechtigt. Angenommen bei der ersten Anweisung im Block (FFilePath:= dlgOpenSQL.FileName;) tritt eine Exception auf (ich weiß das es unwahrscheinlich ist) so wird versucht im except teil aFStream.Free aufzurufen obwohl aFStream irgendwo ins Nirwana zeigt und somit kracht es gewaltig.

also einfach so:
Delphi-Quellcode:
aFStream := nil;
try
  FFilePath:= dlgOpenSQL.FileName;
  aFStream:= TFileStream.Create(FFilePath,fmOpenRead);
  lblFile.Caption:= dlgOpenSQL.FileName;
  btnProtocol.Enabled:= True;
except
  on e: Exception do
    begin
      MessageDlg('Fehler beim Laden der Datei!'#13#10+e.Message,mtError,[mbOk],0);
      aFStream.Free;
    end;
end;

DeddyH 27. Nov 2009 09:02

Re: <Variable> möglicherweise nicht initialisiert
 
Aber was geschieht mit dem Stream, wenn keine Exception auftritt?

SirThornberry 27. Nov 2009 09:05

Re: <Variable> möglicherweise nicht initialisiert
 
du Antwort kennst du doch selbst :wink: Du hast natürlich recht das dort vergessen wird aufzuräumen. Man könnte das allerdings auch als letzte Anweisung im try machen (vor dem except) wobei das natürlich nicht die schönste Lösung ist.
Grundsätzlich liegt hier im Codedesign ein Denkfehler vor.

ToFaceTeKilla 27. Nov 2009 09:09

Re: <Variable> möglicherweise nicht initialisiert
 
@DeddyH:
Hm stimmt. Aber mir fällt grad auf, dass sich an den Block noch was anschließt:
Delphi-Quellcode:
 if Assigned(aFStream) then
   Try
   ...
   Finally
     aFStream.free    
   End;
Also das free`en im Exception-Teil, soll im Fehlerfall aufgerufen werden.
Andererseits: in deinem Code wird aFStream doch auch nicht freigegeben, wenn eine Exception auftritt.

EDIT:
Ok hab es jetzt so gelöst:
Delphi-Quellcode:
aFStream:= nil;
aSStream:= nil;
try
  try
    FFilePath:= dlgOpenSQL.FileName;
    aFStream:= TFileStream.Create(FFilePath,fmOpenRead);
    aSStream:= TStringStream.Create(aStr);
    if Assigned(aFStream) then
    ...
  finally
    aFStream.free;
    aSStream.free;
  end;
except
  on e: Exception do
    MessageDlg('Fehler beim Laden der Datei!'#13#10+e.Message,mtError,[mbOk],0);
end;
Danke für den Denkanstoß :thumb:

edit 2&3: Code berichtigt.

DeddyH 27. Nov 2009 09:21

Re: <Variable> möglicherweise nicht initialisiert
 
Zitat:

Zitat von ToFaceTeKilla
Andererseits: in deinem Code wird aFStream doch auch nicht freigegeben, wenn eine Exception auftritt.

Wenn beim Erzeugen des Streams ein Fehler auftritt, gibt es keinen Stream, den man freigeben könnte und es wird in den except-Block gesprungen. In allen anderen Fällen wird der Stream im finally garantiert freigegeben.

ToFaceTeKilla 27. Nov 2009 09:30

Re: <Variable> möglicherweise nicht initialisiert
 
Zitat:

Zitat von DeddyH
Zitat:

Zitat von ToFaceTeKilla
Andererseits: in deinem Code wird aFStream doch auch nicht freigegeben, wenn eine Exception auftritt.

Wenn beim Erzeugen des Streams ein Fehler auftritt, gibt es keinen Stream, den man freigeben könnte und es wird in den except-Block gesprungen. In allen anderen Fällen wird der Stream im finally garantiert freigegeben.

Stimmt, da is was dran. Das war mir so noch gar nicht klar :oops:
Danke fürs Erleuchten ;-)


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:19 Uhr.

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