AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein Prüfung auf Assigned(MyObject) true obwohl MyObject nicht initialisiert wurde

Prüfung auf Assigned(MyObject) true obwohl MyObject nicht initialisiert wurde

Ein Thema von freejay · begonnen am 23. Mai 2019 · letzter Beitrag vom 25. Mai 2019
Antwort Antwort
Seite 2 von 2     12
freejay

Registriert seit: 26. Mai 2004
Ort: Nürnberg
185 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#11

AW: Prüfung auf Assigned(MyObject) true obwohl MyObject nicht initialisiert wurde

  Alt 23. Mai 2019, 13:26
Hallöle...

Besser...
Delphi-Quellcode:
procedure TfMain.Button1Click(Sender: TObject);
var
  In_A: string;
  slShow: TStringList;
begin
  In_A := '';

  slShow := TStringList.Create;
  try
    if In_A = 'then
      exit;
     
  finally
    slShow.Free;
  end;
end;
Danke! Da hast Du natürlich recht: So setze ich es jetzt auch in meinen echten Projekten um...
[Delphi 10.2 Tokyo; Win10; MySQL]
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
6.771 Beiträge
 
Delphi 10.3 Rio
 
#12

AW: Prüfung auf Assigned(MyObject) true obwohl MyObject nicht initialisiert wurde

  Alt 23. Mai 2019, 13:26
Wobei die Initialisierung von In_A streng genommen redundant ist, da strings als managed type automatisch initialisiert wird. Der Lesbarkeit halber würde ich das aber schon so lassen.

Sollte es hier nicht eine Compilerwarnung geben?
Die Zeile "slShow := TStringList.Create;" sollte vor dem try stehen.
Nein, das ist durchaus ein gängiges Muster und erst recht vom Compiler nicht zu beanstanden.
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Schokohase

Registriert seit: 17. Apr 2018
777 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#13

AW: Prüfung auf Assigned(MyObject) true obwohl MyObject nicht initialisiert wurde

  Alt 23. Mai 2019, 13:38
Sollte es hier nicht eine Compilerwarnung geben?
Die Zeile "slShow := TStringList.Create;" sollte vor dem try stehen.
Nein, das ist durchaus ein gängiges Muster und erst recht vom Compiler nicht zu beanstanden.
Beispiel:
Delphi-Quellcode:
procedure foo;
var
  sl1, sl2: TStringList;
begin
  sl1 := nil;
  sl2 := nil;
  try

    // beliebiger code hier

    sl1 := TStringList.Create;

    // beliebiger code hier

    sl2 := TStringList.Create;

    // beliebiger code hier

  finally
    sl1.Free;
    sl2.Free;
  end;
end;
Wenn an irgendeiner Stelle von "beliebiger code hier" eine Exception geworfen wird, oder mit Exit der Code verlassen werden soll, dann wird der finally-Block ohne Probleme abgearbeitet.
  Mit Zitat antworten Zitat
Dennis07

Registriert seit: 19. Sep 2011
Ort: Deutschland
338 Beiträge
 
Delphi 10.2 Tokyo Enterprise
 
#14

AW: Prüfung auf Assigned(MyObject) true obwohl MyObject nicht initialisiert wurde

  Alt 23. Mai 2019, 23:18
Das Problem wird nur sein, dass du dann nicht mehr den ursprünglichen Fehler mittels Exception-Handling abfangen kannst, weil du dann im finally -Abschnitt eine Access-Violation bekommst.
Auch geht das so nur bei objekten, die nicht voneinander abhängig sind.
Dennis
  Mit Zitat antworten Zitat
Schokohase

Registriert seit: 17. Apr 2018
777 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#15

AW: Prüfung auf Assigned(MyObject) true obwohl MyObject nicht initialisiert wurde

  Alt 23. Mai 2019, 23:49
Das Problem wird nur sein, dass du dann nicht mehr den ursprünglichen Fehler mittels Exception-Handling abfangen kannst, weil du dann im finally -Abschnitt eine Access-Violation bekommst.
Probier es aus, so gibt es eben kein Problem und die Exceptions funktionieren wunderbar.

BTW: Du weißt, dass die Methode Free auf nil prüft bevor diese den Destructor aufruft? Also davon kann es keine AV geben.
Auch geht das so nur bei objekten, die nicht voneinander abhängig sind.
Dann muss man eigentlich nur auf die Reihenfolge bei der Freigabe achten (oder darf gar nicht freigeben, wenn man das Lifetime-Management delegiert habe)

Geändert von Schokohase (23. Mai 2019 um 23:52 Uhr)
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
536 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#16

AW: Prüfung auf Assigned(MyObject) true obwohl MyObject nicht initialisiert wurde

  Alt 24. Mai 2019, 13:27
Puh, da ist einiges falsch.

Das Create gehört vor den try.

Dass das obige "sl1.Free;" funktioniert, liegt vielleicht nur daran, dass bei TStringList zufällig nichts schlimmes passiert.
Free ruft Destroy() auf und wenn dort auf Felder zugegriffen wird, dann gibt es zwangsläufig eine Schutzverletzung.
Wenn bei obigem "// beliebiger code hier" eine Exception passiert, dann bleibt sl1 nil

"Dass die Methode Free auf nil prüft" ist auch falsch. FreeAndNil prüft dagegen.
  Mit Zitat antworten Zitat
Benutzerbild von Uwe Raabe
Uwe Raabe

Registriert seit: 20. Jan 2006
Ort: Lübbecke
6.771 Beiträge
 
Delphi 10.3 Rio
 
#17

AW: Prüfung auf Assigned(MyObject) true obwohl MyObject nicht initialisiert wurde

  Alt 24. Mai 2019, 14:39
"Dass die Methode Free auf nil prüft" ist auch falsch. FreeAndNil prüft dagegen.
Du irrst gewaltig! In beiden Fällen!

Delphi-Quellcode:
procedure TObject.Free;
begin
// under ARC, this method isn't actually called since the compiler translates
// the call to be a mere nil assignment to the instance variable, which then calls _InstClear
{$IFNDEF AUTOREFCOUNT}
  if Self <> nil then
    Destroy;
{$ENDIF}
end;
Delphi-Quellcode:
procedure FreeAndNil(var Obj);
{$IF not Defined(AUTOREFCOUNT)}
var
  Temp: TObject;
begin
  Temp := TObject(Obj);
  Pointer(Obj) := nil;
  Temp.Free;
end;
{$ELSE}
begin
  TObject(Obj) := nil;
end;
{$ENDIF}
Uwe Raabe
Certified Delphi Master Developer
Embarcadero MVP
Blog: The Art of Delphi Programming
  Mit Zitat antworten Zitat
Schokohase

Registriert seit: 17. Apr 2018
777 Beiträge
 
Delphi 10.2 Tokyo Starter
 
#18

AW: Prüfung auf Assigned(MyObject) true obwohl MyObject nicht initialisiert wurde

  Alt 24. Mai 2019, 14:45
Puh, da ist einiges falsch.

Das Create gehört vor den try.

Dass das obige "sl1.Free;" funktioniert, liegt vielleicht nur daran, dass bei TStringList zufällig nichts schlimmes passiert.
Free ruft Destroy() auf und wenn dort auf Felder zugegriffen wird, dann gibt es zwangsläufig eine Schutzverletzung.
Wenn bei obigem "// beliebiger code hier" eine Exception passiert, dann bleibt sl1 nil

"Dass die Methode Free auf nil prüft" ist auch falsch. FreeAndNil prüft dagegen.
Bitte, erst informieren, dann dementieren.

Das Create kann stehen wo will.
Delphi-Quellcode:
var
  f: TObject;
begin
  f := TObject.Create;
  try

  finally
    f.Free;
  end;
end;
oder
Delphi-Quellcode:
var
  f: TObject;
begin
  f := nil;
  try
    f := TObject.Create;

  finally
    f.Free;
  end;
end;
Ist beides gleichwertig. Die zweite Variante macht allerdings nur dann richtig Sinn, wenn man mehrere Instanzen mit einem Resourcen-Schutzblock absichern kann/will.

Das mit dem Free und nil hat Uwe ja schon erklärt.

Manchmal ist Erkenntnis nur einen Klick entfernt und da wundert man sich halt schon manchmal über das was hier an Wissen offenbart wird.
  Mit Zitat antworten Zitat
freimatz

Registriert seit: 20. Mai 2010
536 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#19

AW: Prüfung auf Assigned(MyObject) true obwohl MyObject nicht initialisiert wurde

  Alt 25. Mai 2019, 12:40
Dazu gibt es ja zum Glück das Forum.
Asche auf mein Haupt. Tut mir leid.
Ich war mir so sicher ... War das schon immer so?

Lustig: Habe nach "procedure TObject.Free;" bei mir gesucht und gefunden:
Delphi-Quellcode:
procedure TObject.Free;
begin
  Dispose(PObject(@Self), Done);
end;
Allerdings stand oben drin "Turbo Pascal Version 7.0"

Geändert von freimatz (25. Mai 2019 um 12:57 Uhr)
  Mit Zitat antworten Zitat
dummzeuch

Registriert seit: 11. Aug 2012
Ort: Essen
424 Beiträge
 
Delphi 2007 Professional
 
#20

AW: Prüfung auf Assigned(MyObject) true obwohl MyObject nicht initialisiert wurde

  Alt 25. Mai 2019, 16:28

Besser...
Delphi-Quellcode:
procedure TfMain.Button1Click(Sender: TObject);
var
  In_A: string;
  slShow: TStringList;
begin
  In_A := '';

  slShow := TStringList.Create;
  try
    if In_A = 'then
      exit;
     
  finally
    slShow.Free;
  end;
end;
Danke! Da hast Du natürlich recht: So setze ich es jetzt auch in meinen echten Projekten um...
Naja, das ist zwar nicht falsch, erzeugt aber, wenn In_A = '', unnötigerweise die Stringlist, nur um sie dann sofort wieder freizugeben. Bei einer Stringlist ist das noch relativ egal, aber bei komplexeren Klassen kann der Constructor schonmal einiges an Ressource fressen, so dass man sie nur erzeugen sollte, wenn wirklich notwendig. Die Variante mit slShow := nil vor dem Try ist in dem Fall dann besser.
Thomas Mueller

Geändert von dummzeuch (25. Mai 2019 um 16:31 Uhr)
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 12:06 Uhr.
Powered by vBulletin® Copyright ©2000 - 2019, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2019 by Daniel R. Wolf