質問者
MFC をスタティックリンクするプログラムで、ランタイムタイプ情報( typeid )を使用するとメモリリーク する

質問
-
こんにちは。
VisualSdtuio 2005 でコマンドラインプログラムをウィザードで作成し、プロジェクトのプロパティで
「全般」の「MFC の使用」の項目を 「スタティック ライブラリで MFC を使用する」に変更し、以下のように
typeid を使用するとメモリリークが発生します。
int _tmain( int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;// MFC を初期化して、エラーの場合は結果を印刷します。
if( ! AfxWinInit( ::GetModuleHandle( NULL ), NULL, ::GetCommandLine(), 0 ))
{
// TODO: 必要に応じてエラー コードを変更してください。
_tprintf(_T("致命的なエラー: MFC の初期化ができませんでした。\n"));
nRetCode = 1;
}
else
{
puts( typeid( ::AfxGetApp()).name()) ;
}return nRetCode ;
}マイクロソフトのサイトに、
「FIX: ランタイム タイプ情報を使用することによりメモリ リーク レポートが発生することがあります。」
http://support.microsoft.com/kb/140670/ja
というドキュメントを見つけましたが、対象が VC4.0 と VC4.1 と古くVisualSdtuio 2005 でも発生し続けるものかわかりません。ドキュメント同様に無視できるものならいいのですが、
デバッグ情報にメモリリーク情報として出てしまうので、対処方法がありましたら教えて
頂けないでしょうか ?
すべての返信
-
KB については、探していないので何とも言えませんが、ちょこっと潜ってみた感じでは、リリースのタイミングの問題で、メモリーリークが報告されているように思われます。
動作としては、type_info オブジェクト(typeid() で返されるオブジェクト)に、必要になったタイミングで名前を malloc してくる格好になっているので、結果としてメモリーリークが出てしまうということになりますね。
実際は、プロセス解放のタイミングでオブジェクトも破棄されるので問題はないといえます。
が、どうしても取り除きたいのであれば、typeid を使っても name() は呼ばないなどを行わないと無理だと思います。
-
通常、オブジェクトの型が特定のものかを typeid で判断するのであれば、
CHoge hoge;
if( typeid( hoge ) == typeid( CHoge ) ){
// 同じ時の処理...}
という形になるのではないかと思います。
また、MFC 限定でなおかつそのクラスが CObject の派生クラスなのであれば、DECLARE_DYNAMIC などを利用することでも型情報を持たせることができます(こちらは、RTTI とは別の仕組みなので、リークしません)。
サンプルだけでは状況がつかめないため、判断しきれないのですが、何らかの理由でオブジェクトの型名の文字列が必要というのはそう多くはないのではと思いますが。