• ベストアンサー

VC++ オリジナルDLLを使用するとアプリを終了させる時にメモリリークする

VisualStudio2005 C++ユーザです。 メモリリークの解決の糸口を探しています。 オリジナルDLLでクラスを作成しそれをオリジナルアプリ側で宣言だけして実行、アプリを閉じると「Detected memory leaks!」と表示されます。 アプリもDLLもデフォルト状態での使用のため、何が原因かさっぱりです。 解決の手引きお願い致します。 ●作成DLL ・DLLの種類>MFC拡張DLL ・クラスはエクスポートするように記述変更  >class AFX_EXT_CLASS CHogehoge : public CObject ・メンバ関数 InitHogehoge() として「int i=0;」のみ記述 ●作成アプリ(MDI形式) ・プロジェクト形式 MFC標準 ・共有DLLでMFCを使用に設定 ・以下のようにクラスの宣言  >例 void CTestApp::OnAppAbout()内にCHogehoge abc;を宣言 ●現象 ・アプリを終了させた時に以下が出力される Detected memory leaks! Dumping objects -> d:\実験\f_tool\f_tool.cpp(53) : {65} client block at 0x003B9028, subtype c0, 64 bytes long. a CDynLinkLibrary object at $003B9028, 64 bytes long a CDynLinkLibrary object at $003B9028, 64 bytes long {59} client block at 0x003B3298, subtype c0, 64 bytes long. a CDynLinkLibrary object at $003B3298, 64 bytes long a CDynLinkLibrary object at $003B3298, 64 bytes long Object dump complete. F_TOOL.DLL Terminating! プログラム '[192] Test.exe: ネイティブ' はコード 0 (0x0) で終了しました。 ●特記事項 エクスポートしたクラス自体は参照出来ているので基本的なミスはないつもり。 出力の「d:\実験\f_tool\f_tool.cpp(53) : {65} client block at ・・・.」はDLL側の「new CDynLinkLibrary(F_TOOLDLL);」行。 宜しくお願い致します。

質問者が選んだベストアンサー

  • ベストアンサー
  • jgk
  • ベストアンサー率75% (104/138)
回答No.2

new CDynLinkLibrary(F_TOOLDLL);はAfxTermExtensionModule(F_TOOLDLL);によって解放されるのですが、出力を見ればわかりますが、解放より前にリークの検出が行われている為にリークが報告されているだけで、メモリリークしてないと思われます。

sakuzo3
質問者

お礼

ありがとうございます。 なるほど!と思いたいのですが、なぜ「解放より前にリークの検出が行われている」のか知りたい気もします・・・。 しかし理屈抜きでも前へ進みたいため今は「そんなもんなんだ」と覚えておきます。

その他の回答 (1)

  • keibou21
  • ベストアンサー率31% (18/58)
回答No.1

よくわかりませんが、 new CDynLinkLibrary(F_TOOLDLL); とCDynLinkLibraryオブジェクトを動的生成してますね。 この生成したオブジェクトをdeleteしていますか?

sakuzo3
質問者

補足

早速の回答ありがとうございます。 このオブジェクトをDeleteするようなことはしていません。 このオブジェクトはDLLMain()内にあるのですが、教科書通りとなっており何も手を入れていません。 ※教科書=「日経BP プログラミング Visual C++.NET Vol.1 基礎編 第20章」 DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved) {  // lpReserved を使う場合はここを削除してください  UNREFERENCED_PARAMETER(lpReserved);  if (dwReason == DLL_PROCESS_ATTACH)  {   TRACE0("F_TOOL.DLL Initializing!\n");   // 拡張 DLL を 1 回だけ初期化します。   if (!AfxInitExtensionModule(F_TOOLDLL, hInstance))   return 0;   new CDynLinkLibrary(F_TOOLDLL);  }  else if (dwReason == DLL_PROCESS_DETACH)  {   TRACE0("F_TOOL.DLL Terminating!\n");   // デストラクタが呼び出される前にライブラリを終了します   AfxTermExtensionModule(F_TOOLDLL);  }  return 1; // OK }

関連するQ&A

  • メモリリークの件

    メモリリークについて教えてください。 最近VC++を勉強中なのですが、メモリリークというものを知り、_CrtDumpMemoryLeaks()をしたところ、以下のコメントが出力されました。 [コメント] Detected memory leaks! Dumping objects -> strcore.cpp(118) : {71} normal block at 0x00344978, 20 bytes long. Data: < cmd.> 01 00 00 00 07 00 00 00 07 00 00 00 63 6D 64 2E {48} client block at 0x003428E8, subtype 0, 64 bytes long. a CDynLinkLibrary object at $003428E8, 64 bytes long {43} client block at 0x00342720, subtype 0, 64 bytes long. a CDynLinkLibrary object at $00342720, 64 bytes long {41} client block at 0x003425D0, subtype 0, 64 bytes long. a CDynLinkLibrary object at $003425D0, 64 bytes long Object dump complete. スレッド 0x584 終了、終了コード 0 (0x0)。 上記のコメントから、メモリリークを起こしていることはわかりました。ただ、strcore.cppというクラスは作成していないのですが、エラーが出ます。 多分他の関数から呼ばれているクラスだと思うため、クラス等をコメントアウトして調べたのですが、エラーがまだ出力されます。 (Data: < cmd.> 01 00 00 00 07 00 00 00 07 00 00 00 63 6D 64 2Eここは自作クラス上の問題だと思います。) newとかの解放はしているのですが、他にメモリリークをする原因ってあるのでしょうか?

  • メモリリークについて

    VC6.0でデバッグ実行すると Detected memory leaks! Dumping objects -> ソースファイル名(932) : {136739} normal block at 0x00FD4AC0, 0 bytes long. Data: <> メッセージがあり メモリがリークしているようです メッセージやソースから察するに 0バイトの領域を確保し それを解放したときに起こっているようです 領域をmallocして 解放ではNULLでなければ解放 という処理はしてはいけないことなのでしょうか 0バイトの領域を確保した場合 又は0バイトの領域を確保しないように 処理しないといけないのでしょうか? 知識のある方よろしくお願い致します

  • _dupenv_s関数でメモリリーク

    VC++2005のMFCにてアプリを作成しています。 環境変数「TEST_ENV」の値を「OFF」にあらかじめ設定し、 _dupenv_s()関数にて変数の値を読込むプログラムなのですが、 プログラムをデバッグモードで実行し出力欄を見ると、 「Detected memory leaks!」と表示され、 原因箇所を探ると、どうやら ============================================== char* pGetEnv; size_t len; _dupenv_s( &pGetEnv, &len, "TEST_ENV" );←ここ ============================================== にて発生しているようです。 MSDNによると、lenにはバッファ容量を指定とあるので、 原因として、lenに何も指定されておらず、リークが発生していると考え、 Webで方法を色々調べたのですが、どのサイトも同じような書き方で、 解決法が分かりません。 どなたかご存知の方おられましたら、ご教授お願い致します。 なお下記にメッセージログを記載します。 Detected memory leaks! Dumping objects -> {73} normal block at 0x003A7018, 4 bytes long. Data: <OFF > 4F 46 46 00

  • Visual Studio2008でのメモリリーク

    プログラムを組んでいて、終了すると 以下のようなメモリリークがでました。 desktop\emptyproject ?d?a?E?μ\dxut\core\dxut.cpp(3385): DXUTCleanup3DEnvironment hr=DXUTERR_NONZEROREFCOUNT (0x80040904) D3DX: MEMORY LEAKS DETECTED: 363 allocations unfreed (322368 bytes) D3DX: Set    HKLM\Software\Microsoft\Direct3D\D3DXBreakOnAllocId=0x1a35 to debug MSDNでは DXUTERR_NONZEROREFCOUNT Direct3D デバイスがゼロ以外のリファレンス カウントを持っているため、一部のオブジェクトが解放されませんでした。 とありますが、この意味もよく分かりません。 今までのメモリリークは Dumping objects -> {343} normal block at 0x0207F288, 2240 bytes long. のように割り当てられたブロックが分かりましたが、 上の様なメモリリークは初めてで、 文からメモリリークの原因を検出することができないでいます。 何故、下ではなく上の様なエラー文になるんでしょうか?

  • インターネット使用時の強制終了

    最近インターネット使用時に頻繁に強制終了されてしまい本当に困っています。 もしこれを見てなにか解ることがありましたら、教えてください。 詳細は次の通りです。 EXPLORER のページ違反です。 モジュール : KERNEL32.DLL、アドレス : 0187:bff7b9a6 Registers: EAX=00000000 CS=0187 EIP=bff7b9a6 EFLGS=00000246 EBX=8424b3f8 SS=018f ESP=019bfd58 EBP=8424b3e4 ECX=c60b5bb0 DS=018f ESI=8424b3f8 FS=542f EDX=81656964 ES=018f EDI=0000019c GS=0000 Bytes at CS:EIP: ff 76 04 e8 93 89 ff ff 5e c2 04 00 56 8b 74 24 Stack dump: 019bfd90 7f86de25 8424b3f8 019bfd90 0047ab1d 7f860000 75a4c3ae 00000000 75a4c75b 019bfd90 019bfd8c 019bfd88 019bfd8c 0000019c 0000019c 04580024 以上です。よろしくお願いします。

  • kernel32.dllがおかしいといって必ずアプリが立ち上がらない

    Adobe Photoshopを立ち上げると、必ず以下のメッセージが出てしまい、起動できません。 仕方ないので、アプリケーションを削除して再インストールをしたのですが、何回やってもNGでした。 スキャンディスクでも引っかからないし、仕方ないので kernel32.dllだけを入れ替えようとおもうのですが、 1)やり方は、どのようにすればよいのですか? 1.1)他のマシンのものをコピーしてよいのでしょうか? 2)もしくはまったく他に良い解決方法があるませんか? 3)このようなシステムエラーが出たときにスキャンディスクよりも強力なソフトは販売されているのでしょうか?お勧めが有りましたら教えてください。 ----------------------------------------------- PHOTOSHP のページ違反です。 モジュール : KERNEL32.DLL、アドレス : 017f:bff7b9f5 Registers: EAX=790d92e0 CS=017f EIP=bff7b9f5 EFLGS=00010202 EBX=009dedf8 SS=0187 ESP=008e0000 EBP=008e0024 ECX=008e1df8 DS=0187 ESI=00000001 FS=44a7 EDX=00000001 ES=0187 EDI=81a41b88 GS=0000 Bytes at CS:EIP: 56 57 89 65 e8 75 04 33 c0 eb 54 85 c0 74 4b c7 Stack dump: 009dedf8 790d92e0 00000001 009dedf8 790d92e0 008e1df8 bffc0ab0 bff79250 ffffffff 008e1e08 bff7cef4 790d92e0 00000001 790d9401 790d92e0 008e1e30

  • MFC VC++ 6.0 使用 

    //自分が作ったクラス class Point{ double a; double b; private; Point(double A,double B){a=A,b=B} double GetA(){return a} double GetB(){return b} } //グローバル宣言 Point point(12.0,4.5); //MFCから 与えられたもの CModel::OnDraw(CDC* pDC){ pDC->TextOut(0,0,"HELLO"); } //自分で追加した関数 クラスウィザード を 作ったときにできた。 CModel::MyMeasure() { double answer = point.GetA-point.GetB; Invalidiate(); } 今やっていること やりたいことを簡略化して かきました。 MyMeasure は 自分が クラスウィザードを作成したときに追加した関数です。この 中で 再描画をしたいのですが "HELLO"が 表示されない ばかりか 自動的に クライアント領域(? 実行画面 最初に "HELLO"が でてくる 画面)が消えてしまいます。 どうしてなのでしょうか? これは あくまで 簡略化したものです。 もしかしたら 初歩的な問題なのかもしれませんが、できるだけ 詳しく説明おねがいします。。初心者のため(--) お願いします。

  • Detected memory leaks!

    VS2010を使用しています。 複数人で同じプロジェクトを編集しています。 いつからか「Detected memory leaks!」が多発するようになり、Dumping Objectsの結果からいくつかは修正できたのですが、 ---------------------------------------- f:\dd\vctools\vc7libs\ship\atlmfc\src\mfc\strcore.cpp(156) : {34985} normal block at 0x05ECE620, 104 bytes long. Data: < }R+ + > 84 CF 7D 52 2B 00 00 00 2B 00 00 00 01 00 00 00 ---------------------------------------- 上記の内容だけは意味がわかりません。 他の回答に「_CrtDumpMemoryLeaks」の実行場所をできるだけ後にするというようなことで対策できたようですが、このプロジェクトでは、記述していません。(明示的には実行していない) 何か、何かアドバイスをいただけたら助かります。 よろしくお願いいたします。

  • VC6でDLL(COM+)作成中にエラーが出ました。

    VC6でATL COM AppWizardでDLLを作成しています。 インターフェースメソッドを追加したところ、 (1)の場合はうまくいきましたが、(2)の場合は、エラーと警告が2つ出ました。 理屈がわかっていないので対処方法がわからないのですが、何が原因なのでしょうか? やりたいことは、戻り値1つでなく、3つの戻り値が必要で、 引数4つのうち、最初は関数へ計算の元となる文字列を送り、残りの3つはint型ポインタを与えて、関数内で結果をセットし、呼び出し元でも使えるようにしたいので、このようにしました。通常のC?ではうまくいっていました。 あと読んだ方が良い書籍も探しています。 COM+?について詳しい方、教えてください。 ※COM+というのはVB2005やC#でも健在なのでしょうか? (1) 戻り値のタイプ: HRESULT メソッド名: Test1 パラメータ: なし (2) 戻り値のタイプ: HRESULT メソッド名: Test2 パラメータ: [in] char* a, [in,out] int* b, [in,out] int* c, [in,out] int* d →※ここが間違い? ===== エラー内容 ===== error C2259: 'CComObject<class CTest>' : 抽象クラスあるいは構造体のオブジェクトが宣言されています。 クラス テンプレートのメンバ関数 'long __stdcall ATL::CComCreator<class ATL::CComObject<class CTest> >::CreateInstance(void *,const struct _GUID &,void ** )' のコンパイル中 warning C4259: 'long __stdcall ITest::Test2(unsigned char *,int *,int *,int *)' : 純粋仮想関数は定義されていません。 'Test2' の宣言を確認してください。 クラス テンプレートのメンバ関数 'long __stdcall ATL::CComCreator<class ATL::CComObject<class CTest> >::CreateInstance(void *,const struct _GUID &,void ** )' のコンパイル中 error C2259: 'CComObject<class CTest>' : 抽象クラスあるいは構造体のオブジェクトが宣言されています。 クラス テンプレートのメンバ関数 'long __stdcall ATL::CComCreator<class ATL::CComObject<class CTest> >::CreateInstance(void *,const struct _GUID &,void ** )' のコンパイル中 warning C4259: 'long __stdcall ITest::Test2(unsigned char *,int *,int *,int *)' : 純粋仮想関数は定義されていません。 'Test2' の宣言を確認してください。 クラス テンプレートのメンバ関数 'long __stdcall ATL::CComCreator<class ATL::CComObject<class CTest> >::CreateInstance(void *,const struct _GUID &,void ** )' のコンパイル中

  • VCのDLL内でmallocした構造体をVBで使用

    題名通りですが、 VC側のDLLにてmallocで構造体の領域を確保しています。 この領域をVB側で使用したいのですが、やり方がわかりません。 イメージは Public Declare Function GetData Lib "xxx.dll" (ByRef datas As KOUZOUTAI, ByRef dataCnt As Long) As Boolean みたいな形で、datasに構造体のデータ、及び dataCntに領域確保したデータ数を取得出来ればなと思っております。 VB側では、これもイメージですが、 dim datas() as KOUZOUTAI dim dataCnt as long GetData(datas, dataCnt) for cnt=0 to dataCnt - 1 msgbox datas(cnt).a msgbox datas(cnt).b msgbox datas(cnt).c next みたいな感じで処理をしたいと思っております。 お聞きしたい事は 1)そもそも可能なのか? 2)declare宣言のdatasのところが???です。 3)dim datas() as KOUZOUTAIのところも宣言が???です。 4)datas(cnt).a等としているところも配列?として処理出来るのかが???です。 以上、よろしくお願いします。