动态分配的工作线程在几分钟后泄漏,尽管它不应该

Dynamically allocated worker thread leaks after several minutes although it shouldn't

本文关键字:泄漏 不应该 几分钟 线程 工作 分钟 动态分配      更新时间:2023-10-16

Visual Studio 2010 SP1,32位exe,Dell Core 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;
}

编辑2:自从写这个答案以来,这个问题已经发生了变化。我将答案保持原样,但请注意,它不再与(现已更改的)问题非常相关。


不知道任何泄漏,但丢失类型信息的newvoid*的事情都是完全不必要的

所以,只要删除那些东西。

new=无泄漏。

此外,对于需要new的情况,请使用智能指针进行清理。

这也将有助于防止内存泄漏(尽管不如不做new那样保证,也就是说,您可能会在 Java 中出现内存泄漏,这让许多 Java 程序员大吃一惊)。


编辑:我认为@interjay的评论,"如果你的main函数创建线程的速度比线程可以执行和关闭的速度快,你会看到看起来像泄漏的东西",可能会在明显的内存泄漏方面一针见血。