C++ デストラクターが例外をスローしているか、その可能性があります。
次の 2 つの理由から、C++ デストラクターは例外をスローすべきではありません。1 つ目の理由として、C++ オブジェクトは、例外が許可されていないコンテキストで暗黙的に破棄されます。例えば、例外 E1 をスローするデストラクターを持つオブジェクト X のインスタンスをブロックの中で宣言して、 別の例外 E2 をスローしてそのブロックを終了する場合、 C++ ランタイムは E1 と E2 の両方の例外ハンドラーを実行することはできません。どちらか一方を選択すると、もう片方の例外は失われます。例外を失うことはできないため、C++ ランタイムは、プロセスを直ちに終了する terminate() を呼び出します。
2 つ目の理由として、デストラクターが例外のスローに成功し、例外が正しく処理されたとしても、アプリケーションでメモリーリークが発生します。オブジェクトの削除では、最初にデストラクターが呼び出され、次に delete 演算子が呼び出されます。実際にストレージを解放するのは delete 演算子です。デストラクターが例外をスローして、delete 演算子が呼び出されなかった場合、メモリーリークが発生します。
ID |
問題箇所 |
説明 |
---|---|---|
1 |
例外のスロー |
例外がスローされた場所 |
2 |
定義 |
デストラクターが定義された場所 |
#include <stdio.h> #include <stdlib.h> class Bomb { // bad class throws exception from destructor int x; public: Bomb() : x(0) {} ~Bomb() { throw "boom"; } void * operator new(size_t n) throw() { printf("operator new called\n"); return malloc(n); } void operator delete(void *p) throw() { printf("operator delete called\n"); // never gets here if (p != 0) free(p); } }; void f() { Bomb myBomb; // local variable that will blow up when torn down Bomb *pBomb = new Bomb(); try { delete pBomb; } catch (...) { // Gets here but leaks storage. Print output shows that // operator new was called but operator delete was not. printf("caught exception from destructor\n"); } // program dies here: can't throw two exceptions // ("boom" and "no boom") at the same time. throw "no boom"; // program dies here } int main(int argc, char **argv) { try { f(); } catch (char *message) { printf("f threw %s\n", message); // never gets here } }
© 2010 Intel Corporation. 無断での引用、転載を禁じます。