1

Visual Studio 2010 SP1,32 位 exe,戴尔酷睿 i7。

为清晰而编辑:

我正在追逐生产代码中的一个小内存泄漏。它使用在工作线程上执行的 lambda 将事件分派给侦听器。这是一个关于如何导致泄漏的提炼示例。如果您让它运行足够长的时间(几分钟),该样本就会泄漏。谁能告诉我为什么?我敢肯定,当它被指出时,我会踢自己。谢谢。

#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 回答