none
CRT ライブラリを使用したメモリ リークの検出について RRS feed

  • 質問

  • VC2013 C++をもちいてC++で作成されたdllを,C#から操作するためのdllを作成しています.

    メモリーリークが発生していましたので、

    https://msdn.microsoft.com/ja-jp/library/x98tx3cf.aspx?f=255&MSPPError=-2147217396

    上記を参考にリーク箇所を出力しところ以下の出力を得ることが出来ました.

    Detected memory leaks!
    Dumping objects ->
    {157} normal block at 0x069743D0, 8 bytes long.
     Data: <0 .     > 30 E5 2E 00 00 00 00 00 
    Source.cpp(124) : {153} normal block at 0x0694C710, 4 bytes long.
     Data: <    > 00 00 00 00 
    Object dump complete.

    Source.cpp(124)はSource.cppの124行目でメモリーリークが発生していることがわかりました.

    {157} normal block at 0x069743D0はプログラムのどこでリークしていると判断すれば良いのでしょうか?

    何卒ご教授宜しく御願い致します.

    2016年4月12日 23:33

回答

  • >{157} normal block at 0x069743D0はプログラムのどこでリークしていると判断すれば良いのでしょうか?

    Source.cppの「124」行目で確保されたメモリー番号が「153」ですね。
    「157」はそれより後で確保されたメモリーです。なので

    1.まず、Source.cppの「124」行目にブレークポイントをはって、ブレークさせます。

    2.ウォッチウインドウを開いて次の変数をエントリします。
     {,,msvcr120d.dll}_crtBreakAlloc

    3.この変数は通常 -1 になっているので、これを「157」に変更します。

    4.トレースを再開するか、F5実行します。

    運がよければ、{157} normal block at 0x069743D0 のリークの原因となった
    行でブレークするかもしれません。
    というのは、実行するたびにメモリーの確保番号が変わることが多いため、
    いつも157番目になるとは限らないからです。対象の確保番号を確認しながら
    十数回程度は繰り返してみましょう。

    運よくブレークしたら「呼び出し履歴」をさかのぼり、自分のコードの行まで戻ります。
    それがリークの原因となっている行です。

    2016年4月13日 2:01

すべての返信

  • もし、DLLのプロジェクトのSource.cpp以外で、他の*.cppがありそこでnewを使っている場合は、そのファイルにも以下のコードを追加してください。

    #ifdef _DEBUG
    #ifndef DBG_NEW
    #define DBG_NEW new ( _NORMAL_BLOCK , __FILE__ , __LINE__ )
    #define new DBG_NEW
    #endif
    #endif

    それでも、***.cpp(数字) のように場所を示すリークが表示されないときは、私は怪しい箇所のソースを追うようにしています。(怪しい関数やステートメントをコメントアウトして絞っていったり・・・)

    自分であえて、リークを起こして絞っていく方法もあるようです。
    http://qiita.com/maenotti_99/items/feb4c0bfdcbe085226ef




    2016年4月13日 0:42
  • >{157} normal block at 0x069743D0はプログラムのどこでリークしていると判断すれば良いのでしょうか?

    Source.cppの「124」行目で確保されたメモリー番号が「153」ですね。
    「157」はそれより後で確保されたメモリーです。なので

    1.まず、Source.cppの「124」行目にブレークポイントをはって、ブレークさせます。

    2.ウォッチウインドウを開いて次の変数をエントリします。
     {,,msvcr120d.dll}_crtBreakAlloc

    3.この変数は通常 -1 になっているので、これを「157」に変更します。

    4.トレースを再開するか、F5実行します。

    運がよければ、{157} normal block at 0x069743D0 のリークの原因となった
    行でブレークするかもしれません。
    というのは、実行するたびにメモリーの確保番号が変わることが多いため、
    いつも157番目になるとは限らないからです。対象の確保番号を確認しながら
    十数回程度は繰り返してみましょう。

    運よくブレークしたら「呼び出し履歴」をさかのぼり、自分のコードの行まで戻ります。
    それがリークの原因となっている行です。

    2016年4月13日 2:01
  • ご回答ありがとうございました.

    上記方法で確認できました.

    確認方法をお教えいただき非常に勉強になりました.

    ありがとうございました.

    2016年4月28日 4:25
  • ご回答ありがとうございます.

    自分でリークを起こしていく確認方法を始めて知りました.

    参考にして勉強させていいただきます.

    ありがとうございました.

    2016年4月28日 4:26