我应该在异常处理后释放/销毁异常吗?

时间:2013-07-18 09:05:56

标签: delphi memory-management exception-handling

我正在调试一个delphi程序。

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

我抓住了一个Excetion e并做我需要的事情。现在,当调试程序计数器到达end;下方的行时,如果我用光标悬停e.errorCode,我仍然可以看到它的值。我希望这超出范围,并最终被破坏。

所以,我的问题是:我是否应该在异常处理后释放/销毁异常?

2 个答案:

答案 0 :(得分:18)

运行时在引发异常后获取异常的所有权。你不需要释放它们。

异常在处理它的块的末尾被销毁,如该程序所示:

{$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.

输出:

MyException: Boo
MyException.Destroy
After try/except block

虽然调试器在释放后仍可能显示有关异常的信息,但该行为未定义。编译器理解异常已经离开了作用域,即使调试器不知道这个事实。


如果您希望异常的生命周期超出处理它的except块,那么您需要调用AcquireExceptionObject。一旦你这样做,你就有责任解除你获得生命的例外。

答案 1 :(得分:5)

编译器+ RTL会为您处理,所以不要。

对于在except块结束后仍然有效的e: Exception对象,请参阅此问题:

Why are Delphi objects assigned even after calling .Free?

销毁某些东西并不能保证内存立即失效,只是让它可以重复使用。