Paolo M
Paolo M

Reputation: 12757

Shall I free/destroy exceptions after exception handling?

I'm debugging a delphi program.

except
    on e: TErrorTapeDrive do
        if e.errorCode = 1104 then
            if Assigned(indexDoneEvent) then
                indexDoneEvent;
        // other handling...
    // other handling...
end;

I catch an Excetion e and do what I need. Now, when the debug program counter reach the line just below end;, if I hover e.errorCode with the cursor, I can still see its value. I would expect this was out of scope and, eventually, destroyed.

So, my question is: shall I free/destroy exceptions after exception handling?

Upvotes: 12

Views: 1942

Answers (2)

David Heffernan
David Heffernan

Reputation: 612794

The runtime takes ownership of exceptions after they are raised. You do not need to free them.

The exception is destroyed at the end of the block in which it is handled, as demonstrated by this program:

{$APPTYPE CONSOLE}

uses
  SysUtils;

type
  MyException = class(Exception)
  public
    destructor Destroy; override;
  end;

destructor MyException.Destroy;
begin
  Writeln('MyException.Destroy');
  inherited;
end;

procedure Main;
begin
  try
    raise MyException.Create('Boo');
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
  Writeln('After try/except block');
end;

begin
  Main;
  Readln;
end.

which outputs:

MyException: Boo
MyException.Destroy
After try/except block

Whilst the debugger may still show you information about the exception after it has been freed, that behaviour is undefined. The compiler understands that the exception has left scope, even if the debugger is ignorant of that fact.


If you want an exception's lifetime to extend beyond the except block which handles it then you would need to call AcquireExceptionObject. Once you do that, it becomes your responsibility to free the exception whose lifetime you acquired.

Upvotes: 19

Jens Mühlenhoff
Jens Mühlenhoff

Reputation: 14873

The compiler + RTL takes care of that for you, so don't.

As for the e: Exception object still beeing "valid" after the end of the except block, see this question:

Why are Delphi objects assigned even after calling .Free?

Destroying something doesn't guarantee that the memory is immediatly invalidated, it just makes it available for reuse.

Upvotes: 5

Related Questions