Entry No.
635
|
コンパイラ - コード生成
'finally' ブロックで例外を生成すると、メモリリークが起こる
|
1.02 |
2.01 |
3.0 |
3.01 |
3.02 |
4.0 |
4.01 |
4.02 |
4.03 |
5.0 |
5.01 |
6.0 |
6.01 |
6.02 |
Kylix 1.0 |
Unknown |
Exists |
Exists |
Exists |
Exists |
Exists |
Exists |
Exists |
Exists |
Exists |
Exists |
Exists |
Unknown |
Unknown |
Unknown |
|
|
解説
|
|
Reported by Andreas Hoerstemeier; checked by Jordan Russell
finally ブロックで例外が発生すると、Delphi はメモリリークを起こします。その後 Delphi は元の例外を完全に忘れてしまい、新しい方の例外は発生しますが、元の例外はヒープ領域から削除されません。
サンプルコード:
try
try
raise EZeroDivide.Create('');
finally
raise EUnderflow.Create('');
end;
except
on EZeroDivide do writeln('Zero');
on EUnderflow do writeln('Underflow');
end;
EZeroDivide オブジェクトがヒープに残ったままの状態で、例外ブロックのUnderflowのところまで到達します。これは例外クラスの destroy メソッドをオーバーライドする事で確認出来ます。このようなケースで、どちらの例外がfinallyブロックから出て行くべきかが載っている文献を見つける事は出来ませんでした。どちらでも正しいのかもしれません。
確認者からの注意:
Delphiのヘルプトピック "try..finally 文" には以下ように書かれています。
生成された例外が finally で処理されない場合,その例外は try...finally 文を越えて伝わり,try 節で既に生成されている例外は失われます。したがって,ほかの例外の伝播の妨げにならないよう,ローカルに生成された例外はすべて finally 節で処理するようにしてください。
(訳注: 日本語版 Delphi 5 のヘルプから原文に該当する部分を引用)
しかし、新しい例外の生成がメモリリークを起こすことには言及していません。
|
|
ユーザーからのコメント
|
Jordan Russell
09 Apr 2001 07:31 PM GMT
|
しばらく考えた後、私はこのエントリーを"混乱の元(Gotcha)"から"バグ(Bug)"に変更することに決めました。
"except" 節で新しい例外が発生しても、メモリリークは起りません。
"finally" 節で新しい例外が発生しても、メモリリークが起こるべきではありません。
|
|