Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 931
Paolo M Avatar asked Jul 18 '13 09:07

Paolo M


People also ask

Under what circumstances is exception handling not appropriate?

Don't use exceptions to control logic If you are using exceptions to control the flow of logic, you are probably doing something wrong. If it is acceptable for a method to return a false or null value, then this doesn't require an exception.

Should you catch all exceptions?

Generally, you should only catch exceptions that you know how to handle. The purpose of exceptions bubbling up is to allow other parts of the code catch them if they can handle them, so catching all exceptions at one level is probably not going to get you a desired result.

What is exception handling what will happen if an exception is thrown for which no matching catch () block is defined?

If there is no catch block at the current scope matching the thrown exception, the current scope is exited, and all automatic (local nonstatic) objects defined in that scope are destroyed. The surrounding scope (which might be function scope) is checked for a matching handler.

What happens when an exception object is not caught and handled properly?

What happens if an exception is not caught? If an exception is not caught (with a catch block), the runtime system will abort the program (i.e. crash) and an exception message will print to the console.


2 Answers

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.

like image 152
David Heffernan Avatar answered Sep 30 '22 23:09

David Heffernan


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.

like image 23
Jens Mühlenhoff Avatar answered Sep 30 '22 21:09

Jens Mühlenhoff