Einzelnen Beitrag anzeigen

Benutzerbild von jaenicke
jaenicke

Registriert seit: 10. Jun 2003
Ort: Berlin
9.587 Beiträge
 
Delphi 11 Alexandria
 
#22

AW: Schutzblöcke überflüssig!?

  Alt 30. Sep 2020, 20:36
Hier können jetzt diverse Probleme auftreten.
Wenn man die zwei Free-Anweisungen jetzt in einen Finally-Block setzt - ohne sonstige Fehlerbehandlung - findest Du weder den Fehler besser noch ist Dein Datenbestand besser geschützt noch erhält der Anwender bessere Fehlerinformationen.
Nur der Speicherplatz der zwei Objekte wird wieder freigegeben. Der Aufrufer der Prozedur Überweisung weiß nichts von dem Fehler und das Programm geht davon aus, dass alles passt.
Doch, denn es geht ja um den Fall, dass eine Exception ausgelöst wird, so dass die Freigabe des Objekts übersprungen würde, weil man bei der Exception heraus springt. Dann kann die Exception zwar abgefangen werden, aber der Speicher wird nicht freigegeben.

Und nun nehmen wir mal an der Code wird in einem Programm immer wieder aufgerufen, das länger läuft, z.B. ein Webservice... da ist dann irgendwann trotz sauberer Behandlung der Exceptions der Speicher voll.

Wenn es nur um wenige Aufrufe geht, merkt man in der Tat nicht viel davon. Aber das Programm benutzt eben mehr Speicher als nötig.

Noch schlechter wird es, wenn man in dem Objekt ein Handle auf eine Datei offen hat oder ähnliches, so dass die Datei dann gesperrt bleibt bis das Programm beendet wird.

Und damit man das nicht immer neu bewerten muss, macht es Sinn einfach immer eine korrekte Behandlung solcher potentiellen Probleme einzubauen. Denn sonst müsstest du ja bei jeder Änderung schauen, ob deine Prozedur nicht irgendwo aufgerufen wird, wo dann eine Behandlung nötig wird...

Davon abgesehen bringt ein Ressourcenschutzblock nur etwas, wenn er auch korrekt aufgebaut ist (Konstruktoraufruf vor dem try, sonst springt man bei einer Exception im Konstruktor auch in das finally obwohl die Variable noch gar nicht zugewiesen ist und dann knallt es ggf. dort erneut):
Delphi-Quellcode:
procedure Run;
begin
  obj1 := TObject.Create;
  try
    Beep;
    obj2 := TObject.Create;
    try
      obj3 := TObject.Create;
      try
        Beep;
      finally
        obj3.Free;
      end;
    finally
      obj2.Free;
    end;
  finally
    obj1.Free;
  end;
end;

try
  Run;
except
  on E: Exception do
  begin
    WriteLog(E);
    UserDialog(Format('Interner Fehler: %s - %s', [E.ClassName, E.Message]));
  end;
end;
Sebastian Jänicke
Alle eigenen Projekte sind eingestellt, ebenso meine Homepage, Downloadlinks usw. im Forum bleiben aktiv!
  Mit Zitat antworten Zitat