2013-07-18 8 views
11

私は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にカーソルを置くと、その値が表示されます。私はこれが範囲外であり、最終的には破壊されたと思います。

私の質問は次のとおりです。例外処理後に例外を解放/破棄する必要がありますか?

+4

エラーコード*が* 1104でない場合、その例外を再発生させることを検討してください。現在、コード*は他のすべてのエラーを黙って無視します。 –

+0

errorCode、@RobKennedyだけでなく、他のタイプの例外も処理されます。 –

+0

いいえ、パオロ。あなたの現在のコードは既に*他の例外の型を無視しています。これは**正しい動作です**。例外を引き起こした問題を修正*するコードを書かない限り、例外を捕まえてはいけません。あなたがそれを修正することができない場合は、それをキャッチしないでください。さもなければ、コールスタックをさらに上にコード化する*拒否*それを修正する機会。 –

答えて

15

実行時に発生した例外の所有権は、実行時に取得されます。あなたはそれらを解放する必要はありません。

このプログラムによって示されるように例外は、それが処理されたブロックの終わりに破壊される:

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

をデバッガ一方でもよいまだお見せそれが解放された後の例外に関する情報は、その動作は定義されていません。コンパイラは、たとえデバッガがその事実を知らないとしても、例外がスコープを去ったことを理解します。


あなたは例外の寿命はあなたがAcquireExceptionObjectを呼び出す必要があり、それを扱うexceptブロックを超えて拡張します。一度それを行うと、あなたが取得した生涯の例外を解放するのはあなたの責任となります。

+0

AcquireExceptionObjectのポイントが良いです。問題のあるトピックにあるためです。 –

+0

'AcquireExceptionObject'のドキュメントは、例外が参照カウントされ、refカウントが増加することも指摘しています。一方、 'ReleaseExceptionObject'は、refカウントを減少させます。 refカウントがゼロになると、例外が解放されます。 –

+0

コンパイラがそれを処理するので、通常は気にしませんが、これらの関数を使用して例外ブロックを超えて例外オブジェクトの寿命を管理することは可能です。 –

5

コンパイラ+ RTLがそれを処理しますので、そうしないでください。

まだ除くブロックの終了後に「有効」beeingてe: Exceptionオブジェクトについては、この質問を参照してください。

Why are Delphi objects assigned even after calling .Free?

何かを破棄すると、メモリはすぐに無効化されることを保証するものではありません、それだけでは、それを再利用できるようにします。