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:自从写这个答案以来,这个问题已经发生了变化。我将答案保持原样,但请注意,它不再与(现已更改的)问题非常相关。
不知道任何泄漏,但丢失类型信息的
new
和void*
的事情都是完全不必要的。
所以,只要删除那些东西。
无new
=无泄漏。
此外,对于需要new
的情况,请使用智能指针进行清理。
这也将有助于防止内存泄漏(尽管不如不做new
那样保证,也就是说,您可能会在 Java 中出现内存泄漏,这让许多 Java 程序员大吃一惊)。
编辑:我认为@interjay的评论,"如果你的
main
函数创建线程的速度比线程可以执行和关闭的速度快,你会看到看起来像泄漏的东西",可能会在明显的内存泄漏方面一针见血。