1

Visual Studio 2010 SP1、32 ビット exe、Dell Core i7。

明確にするために編集:

実稼働コードでの小さなメモリ リークを追跡しています。ワーカー スレッドで実行されるラムダを使用して、イベントをリスナーにディスパッチします。これは、リークがどのように発生するかを抽出した例です。このサンプルは、長時間 (数分) 実行するとリークします。誰でも理由を教えてもらえますか? 指摘されたらきっと自分を蹴るだろう。ありがとう。

#include "stdafx.h"
#include <process.h>
#include <cassert>
#include <tchar.h>
#include <stdlib.h>
#include <stdio.h>

//////////////////////////////////////////////////////////////////////////
template <class Func>
static void __cdecl WorkerThreadProc(void* pData) {
    assert(pData != nullptr);
    Func* pFunc = static_cast<Func*>(pData);
    (*pFunc)();   // Execute the task.
    delete pFunc; // Clean up.
}
//////////////////////////////////////////////////////////////////////////
template <class Func>
static void BeginThread(Func fn) {
    Func* pFn = new Func(fn);
    if (_beginthread(WorkerThreadProc<Func>, 0, pFn) == -1L) {
        errno_t err;
        _get_errno(&err);
        assert(false);        
        delete pFn; // Clean up.
    }
}
//////////////////////////////////////////////////////////////////////////
int main(int, char**)
{
    printf_s("CTRL-C to quit:\n");
    while (true) {
        BeginThread( []()->void{} ); // Launch worker to execute task.
    }
    return 0;
}
4

1 に答える 1

1

編集2:この回答が書かれてから質問が変更されました。答えはそのままにしておきますが、(現在変更されている)質問とはあまり関係がないことに注意してください。


リークについては知りませんが、new-ing とvoid*型情報を失うことの両方が完全に不要です 。

だから、そのようなものを取り除くだけです。

いいえnew= 漏れなし。

newまた、正当な状況では、クリーンアップにスマート ポインターを使用してください。

これは、メモリ リークの防止にも役立ちます (ただしnew、Java でメモリ リークが発生する可能性があることは、Java プログラマーの多くを驚かせることに注意してください)。


編集: @interjay のコメント、「main関数がスレッドを実行して閉じるよりも速くスレッドを作成する場合、リークのように見えるものが表示される」と思いますが、明らかなメモリ リークに関してはおそらく頭に釘を打ちます。

于 2012-09-24T12:08:10.670 に答える