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

Pao*_*o M 12 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;
Run Code Online (Sandbox Code Playgroud)

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

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

Dav*_*nan 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.
Run Code Online (Sandbox Code Playgroud)

哪个输出:

MyException: Boo
MyException.Destroy
After try/except block

虽然调试器在释放后仍可能显示有关异常的信息,但该行为未定义.编译器理解异常已经留下范围,即使调试器不知道该事实.


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

  • 手动异常生命周期管理的一个常见用例是,您希望捕获在一个线程中引发的异常,并在另一个线程中重新显示它.`TThread.FFatalException`就是一个很好的例子. (3认同)

Jen*_*off 5

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

至于e: Exception在except块结束后仍然有效的对象,请看这个问题:

为什么即使在调用后也分配了Delphi对象.Free?

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