C++ VisualStudio中的内存泄漏

C++ VisualStudio中的内存泄漏,c++,multithreading,visual-studio,c++11,memory-leaks,C++,Multithreading,Visual Studio,C++11,Memory Leaks,使用Visual Studio Pro 2012上的std::thread,我发现这段简单代码存在内存泄漏: #include <thread> void f(){} int main(){ std::thread t(f); t.join(); _CrtDumpMemoryLeaks(); return 0;} #包括 void f(){} int main(){ 标准:螺纹t(f); t、 join(); _CrtDumpMemoryLeak

使用Visual Studio Pro 2012上的std::thread,我发现这段简单代码存在内存泄漏:

#include <thread>

void f(){}

int main(){
    std::thread t(f);
    t.join();
    _CrtDumpMemoryLeaks();
    return 0;}
#包括
void f(){}
int main(){
标准:螺纹t(f);
t、 join();
_CrtDumpMemoryLeaks();
返回0;}
Win32输出:

Detected memory leaks!
Dumping objects ->
{293} normal block at 0x00A89520, 44 bytes long.
 Data: <                > 01 00 00 00 00 00 00 00 00 00 00 00 0A 00 00 00 
Object dump complete.
检测到内存泄漏!
转储对象->
0x00A89520处的{293}正常块,44字节长。
数据:<>01 00 00 00 00 00 00 00
对象转储完成。
x64输出:

Detected memory leaks!
Dumping objects ->
{293} normal block at 0x00000000003FCB00, 72 bytes long.
 Data: <                > 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
Object dump complete.
检测到内存泄漏!
转储对象->
0x00000000003FCB00处的{293}正常块,72字节长。
数据:<>01 00 00 00 00 00 00
对象转储完成。
如果我对main方法的前两行进行注释,则没有内存泄漏

它来自哪里

编辑:泄漏仍然存在,代码为:

#include <thread>

void f(){}

int main(){
    {
        std::thread t(f);
        t.join();
    }
    _CrtDumpMemoryLeaks();
    return 0;}
#包括
void f(){}
int main(){
{
标准:螺纹t(f);
t、 join();
}
_CrtDumpMemoryLeaks();
返回0;}

可能是因为thread对象分配了一些数据,并且在转储内存时析构函数没有运行,因此它被视为泄漏


尝试将线程对象、创建和联接放在一个单独的函数中。

当您转储泄漏时,线程析构函数尚未运行。你应该试试:

int main()
{
  {
    std::thread t(f);
    t.join();
  }
  _CrtDumpMemoryLeaks();
  return 0;
}

CrtDumpMemoryLeaks是出了名的不可靠。很可能是标准库在您第一次使用std::thread时故意泄漏一次性分配。要查明是否存在真正的内存泄漏,请尝试以下操作:

for (int i = 0; i < LIMIT; ++i) {
  std::thread t(f); t.join();
}
_CrtDumpMemoryLeaks();
for(int i=0;i

然后查看泄漏大小是否随着限制的增加而增加。如果没有,你就没事。

你不应该在那个位置调用CrtDumpMemoryLeaks——或者如果你接受伪泄漏

静态对象的析构函数尚未运行,这样的对象可以放在内存中。 如果您使用MFC,它将从AFX_状态对象的dtor运行泄漏转储,该转储不会太晚,只会看到真正的泄漏


同时,您可以使用查看该块的分配位置,我打赌调用堆栈将引导您找到RTL领域中的某些函数本地静态,您甚至可以在其dtor上设置一个断点,以查看它在转储后是否确实释放了内存。

我也这么认为,但内存泄漏仍然存在。@Arnaud但无论如何,您应该使用此版本编辑问题。在您发布的一篇文章中,不清楚这些对象是否不再需要。如果我将线程部分放在一个函数中,也会发生这种情况:void g(){std::thread t(f);t.join();}您是对的,泄漏不会随着启动的线程数目的增加而增加。@Arnaud那么这可能是一个静态一次性分配,无需担心。