今年4月にリリースされたばかりのSTLport-5.1.3を使ったら、簡単なMFCアプリコードで
メモリリークが出てしまいました(出力ウィンドウにmemory leak!と表示)。
その対処法をどうかお教え下さい。非MFCアプリでは出ません。
■STLportのビルド設定は下の通りです。
・stlport\stl\config\user_config.h #define _STLP_USE_MFC 1 を有効化
( http://www.nbrains.net/php/pukiwiki/index.php?Build%2FSTLportより)
・stlport\stl\config\host.h #define _STLP_USE_NEWALLOC 1 を有効化
( http://www.emaki.minidns.net/Programming/tools/STLportより)
・build\Makefiles\nmake\vc-common.mak の最下部 OPT_REL と OPT_STATIC_RELマクロに
次のオプション追加
/Ox /G7 /GF /EHsc /arch:SSE2
■テスト用MFCAppの作成手順は下の通りです
・新規作成→プロジェクト→VisualC++プロジェクト→MFC→MFCアプリケーション
→ダイアログベースアプリケーション→完了
・OnInitDialog()のある.cppを開き、#include<vector>を頭に挿入。
且つOnInitDialog()の頭にvector<int> int_v;と書く。
・ビルド→デバッグ実行→終了で、メモリリークの旨が出力ウィンドウに出る。
・vector<int> int_v;の記述を削除すると出なくなる。
環境 WinXP Pro + 全最新パッチ、VC++7.1
以上、どうぞよろしくおねがいします
# すみません、その版のSTLportを確認したわけではありません。
> その対処法をどうかお教え下さい。非MFCアプリでは出ません。
非MFCアプリでは、CRTデバッグ機能をOnにしてますか?
単にOffなだけだったりしませんか。(MFCはOnにする)
また、STLportは設定で自分の情報を保持したりするので、
それが誤検出されたりしたと思いますが、確認されてますか?
>非MFCアプリでは、CRTデバッグ機能をOnにしてますか?
CRTデバッグ機能という物は初耳です。
>STLportは設定で自分の情報を保持したりするので、
>それが誤検出されたりしたと思います
ちょっと良く分かりませんでした。
実はSTL-4.6.2を以前使っており、今回5.1.3にのりかえました(ビルド方法等が大きく変
わっていました)。
状態(コンパイラオプションやSTLportの#defineによる条件コンパイルスイッチ群)を
4.6.2と全く同じにし、ビルドしました。
で、4.6.2の頃から作っていた自作MFCアプリ(メモリリーク報告は出ない)を、上記5.1.3
に変更しただけで今回のような状態になってしまった訳です。
どうやら何日もかけて調べる必要がありそうです...。
> その対処法をどうかお教え下さい。非MFCアプリでは出ません。
>
> >非MFCアプリでは、CRTデバッグ機能をOnにしてますか?
> CRTデバッグ機能という物は初耳です。
int main()
{
int *p = new int;
return 0;
}
このコードの、メモリリークを検出できるでしょうか?
非MFCアプリのデフォルトの設定は、メモリリークを無視します。
#include <crtdbg.h>
#define _CRTDBG_MAP_ALLOC
#define new ::new(_NORMAL_BLOCK, __FILE__, __LINE__)
int main()
{
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
int *p = new int;
return 0;
}
このように書くと、検出できるはずです。
(コンパイルオプションでも設定できるかも)
非MFCで本当にメモリリークが起こるのかどうか、調べてみてはいかがでしょう。
対策は以下の3つになると思うのだが・・・
1.STLport の開発部隊を信じてメモリリーク報告を無視する (要するに何もしない)
2.元の STLport-4.6.2 に戻して 5.1.3 を捨てる
3.メモリリーク報告を深く追求する (STLport-5.1.3 自体のデバッグを行う)
STLport-5.1.3/stlport/stl/config/host.h には気になる記述があるのだが
_STLP_LEAKS_PEDANTIC 周辺
調査するのであれば、たまたまさんがご自分でどーぞ。
聞きかじりで検証していませんが多分このことかと。
これは、STLportがそういう構造をしているからです。
allocatorでメモリ管理するわけですがメモリをプールしています。
で、これを終了時に開放しません。
これはそういう設計であり、メモリリークしないallocatorも用意されています。
stlports\stl\_site_config.hの
//#define _STLP_USE_NEWALLOC 1
という行のコメントアウトを解除すればそちらに切り替わるとの事です。
ある推測では設計ミスとかバグではなく、終了時にはプロセスが確保したメモリは
(グローバルメモリで無い限り)OSやC++ランタイムが勝手に開放してくれる、という
前提でわざとプールを開放しないという事らしいです。
よって、バグではないそうです。
情報が無いか検索してみましたが結構少ないですね。
皆様、どうも有難うございます。因みに非MFCアプリとは、Win32APIのみのGUIアプリ
(AppWizardのWin32プロジェクトで作る)の事です。
>たいちうさん
非MFCアプリでは、やはり白でした。CRTデバッグ機能とは、_CrtSetDbgFlag()だったので
すね。それなら既にやりました。
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF)では、期待通りメモリ
リーク報告が出ました。但しmain()ではなく_tWinMain()ですが。
newや_CrtSetDbgFlag()の行をコメントアウトすると、期待通りリーク報告は出なくなり
ます。
で、newの行をstd::vector<int> int_vに置換しました。が、リーク報告はありません
(CrtSetDbgFlag()は行っています)。
>tetrapodさん
2で行くつもりです。_STLP_LEAKS_PEDANTICを少し調べて治りそうになかったら。
>麩さん
_STLP_USE_NEWALLOCは、冒頭にある通り既に実験済みです。但し_site_config.hは4.6.2
で、5.1.3はhost.hに移っています。又4.6.2では、コメントアウトの有無に関わらず今回
の実験のようなリークは起きません。
>ある推測では設計ミスとかバグではなく、終了時にはプロセスが確保したメモリは
>(グローバルメモリで無い限り)OSやC++ランタイムが勝手に開放してくれる、という
>前提でわざとプールを開放しないという事らしい
本当ですか!?newしたメモリの解放をシステム任せにする、というのは少し考え難い気
がします...。
残念乍、_STLP_LEAKS_PEDANTICをいじっても治りませんでした。
これ以上時間を割けない為、4.6.2へ戻す事に致します。お付き合い下さった方、どうも
有難うございました。