none
メモリリークの可能性 RRS feed

  • 質問

  • いつもお世話になっております。

    ただの勉強のための質問です( Concurrency::Allocを使用しているのは、下記を使用しているプログラムがマルチスレッドだからです)。

    この質問をした理由は、下記コードのFreeで例外が発生したことがあるためです(このコードでは例外が発生したことはありません)。

    下記のコードにリークする可能性は残っていますでしょうか?

    #include <windows.h>
    #include <psapi.h>
    #include <concrt.h>
    #include <iostream>
    
    int main()
    {
     // スレッドの優先順位を引き上げる
     int defaultPriority = ::GetThreadPriority( ::GetCurrentThread() );
     ::SetThreadPriority( ::GetCurrentThread(), THREAD_PRIORITY_HIGHEST );
    
     // パフォーマンスを測定する
     LARGE_INTEGER frequency;
     ::QueryPerformanceFrequency( & frequency );
     LARGE_INTEGER start;
     ::QueryPerformanceCounter( & start );
    
    
     wchar_t * result = nullptr;
     const int loopCount = 100000;
     __try {
      for ( int i = 0; i != loopCount; ++i ) {
       wchar_t * xml = L"<chat name=\"hello\" id=\"1\">abcdefg</chat>";
       const wchar_t * searchStr = ::wmemchr( xml, L'>', ::wcslen( xml ) );
       //const wchar_t * searchStr = ::wcsstr( xml, L">" );
       if ( nullptr != searchStr ) {
        // >.*</chat> .* の文字数を求める。 + 1 = \0
        const int needLen = ( ::wcslen( searchStr + 1 ) - 7 ) + 1;
        result = reinterpret_cast< wchar_t * >( Concurrency::Alloc( needLen * 2 ) );
        if ( nullptr != result ) {
         ::wmemset( result, 0, needLen );
         ::wmemcpy( result, searchStr + 1, needLen - 1 ); // -1 = バッファの\0分を除く
         if ( loopCount != i + 1 ) {
          // 最後に文字を表示するため、ループの最後は解放しない
          // (最適化により影響がでないようにしています( Debugビルドでやっておりますが)
          Concurrency::Free( result );
          result = nullptr;
         }
        }
       }
      }
     }
     __except( EXCEPTION_EXECUTE_HANDLER ) {
      if ( nullptr != result ) {
       Concurrency::Free( result );
       result = nullptr;
      }
     }
    
     LARGE_INTEGER end;
     ::QueryPerformanceCounter( & end );
     // スレッドの優先順位を戻す
     ::SetThreadPriority( ::GetCurrentThread(), defaultPriority );
    
     // μsecで表示.
     std::wcout << ( ( end.QuadPart - start.QuadPart ) * 1000000 / frequency.QuadPart ) << std::endl;
     // 文字列表示
     if ( nullptr != result ) {
      std::wcout << result << std::endl;
      Concurrency::Free( result );
      result = nullptr;
     }
    
     return 0;
    }
    
    以上、よろしくお願いいたします。
    • 編集済み dsa_ma 2011年2月22日 7:46 コード貼り付けに失敗
    2011年2月22日 7:44

回答

  • xmlの内容によってはneedLenが「<0」になる可能性を残していますが、
    そのときはどうなるか考えてみましたでしょうか。
    • 回答としてマーク dsa_ma 2011年2月22日 11:10
    2011年2月22日 8:29
  • んと。。。同時実行ランタイムにはメモリーリークのバグがあります。

    https://connect.microsoft.com/VisualStudio/feedback/details/559305/ppl

    使い方によっては不安定になる場合もあるみたいですが、こちらは詳しく調査してないのでわかりません。

    SP1で治るかどうかはわかりませんが、SP1ベータではリークは検出されなくなってました。ただ、大規模なチェックはしていないので、問題なく使えるか?についてはわかりません。

    提示されたサンプルコードについては細かく見てないのでよくわからんです。


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/
    • 回答としてマーク dsa_ma 2011年2月22日 11:10
    2011年2月22日 10:43

すべての返信

  • xmlの内容によってはneedLenが「<0」になる可能性を残していますが、
    そのときはどうなるか考えてみましたでしょうか。
    • 回答としてマーク dsa_ma 2011年2月22日 11:10
    2011年2月22日 8:29
  • 返信ありがとうございます。

    L"<chat name=\"hello\" id=\"1\" />"

    の場合のことでしょうか?

    考えていませんでした。ありがとうございます。それ以外は・・・大丈夫ですかね。返信がないところを見ますと。

    空の場合は、\0分のみ確保となりますし。

    ありがとうございます。

     

    2011年2月22日 9:33
  • んと。。。同時実行ランタイムにはメモリーリークのバグがあります。

    https://connect.microsoft.com/VisualStudio/feedback/details/559305/ppl

    使い方によっては不安定になる場合もあるみたいですが、こちらは詳しく調査してないのでわかりません。

    SP1で治るかどうかはわかりませんが、SP1ベータではリークは検出されなくなってました。ただ、大規模なチェックはしていないので、問題なく使えるか?についてはわかりません。

    提示されたサンプルコードについては細かく見てないのでよくわからんです。


    わんくま同盟,Microsoft MVP for Visual C++(Oct 2005-) http://blogs.wankuma.com/tocchann/
    • 回答としてマーク dsa_ma 2011年2月22日 11:10
    2011年2月22日 10:43
  • 返信ありがとうございます。

    メモリリークのバグがあるんですか。

    ありがとうございます。

     

    2011年2月22日 11:09