C ++標準、パラグラフ15.1.4は次のように述べています。
スローされる例外の一時コピー用のメモリは、3.7.3.1に記載されている場合を除き、不特定の方法で割り当てられます。その例外に対して実行されているハンドラーがある限り、一時は存続します。
なぜこのコードがクラッシュするのか疑問に思っています(ベストプラクティスではないことはわかっています):
class magicException
{
private:
char* m_message;
public:
magicException(const char* message)
{
m_message = new char[strlen(message) + 1];
strcpy(m_message, message);
}
~magicException()
{
cout << "Destructor called." << endl;
delete[] m_message;
}
char* getMessage()
{
return m_message;
}
};
void someFunction()
{
throw magicException("Bang!");
}
int main(int argc, char * argv[])
{
try
{
someFunction();
}
catch (magicException& ex)
{
cout << ex.getMessage() << endl;
}
return 0;
}
具体的には、スローされたmagicExceptionオブジェクトのデストラクタがcatchブロックの前に呼び出されます。ただし、コピーコンストラクターをクラスに追加すると、次のようになります。
magicException(const magicException& other)
{
cout << "Copy constructor called." << endl;
m_message = new char[strlen(other.m_message) + 1];
strcpy(m_message, other.m_message);
}
次に、コードが機能し、デストラクタが予期された場所(catchブロックの終わり)で呼び出されますが、興味深いことに、コピーコンストラクタはまだ呼び出されません。コンパイラー(最適化がオフになっているVisual C ++ 2008)によって最適化されていますか、それとも何かが足りませんか?