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?
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.
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.
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 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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With