0

简单的测试:

void testMemoryLeak_PthreadCreateJoin(void)
{
   auto taskFunction = [](void*args) -> void*
   {
      return nullptr;
   };
   pthread_t pth;
   int err = pthread_create(&pth, /*attr*/nullptr, taskFunction, /*args*/nullptr);
   pthread_join(pth, nullptr);
}

void main(void)
{
   _CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);
   testMemoryLeak_PthreadCreateJoin();
   testMemoryLeak_PthreadCreateJoin();
   testMemoryLeak_PthreadCreateJoin();
   testMemoryLeak_PthreadCreateJoin();
}

这里说:

线程是分配的资源,您在退出之前没有释放它。你应该打电话pthread_join;这也将消除对您的骇人听闻和不正确的睡眠循环的需要。

有可能即使你修复了这个问题,valgrind 仍然会看到“泄漏”,因为 POSIX 线程的一些实现(我猜你正在使用 glibc/NPTL)缓存并重用线程资源,而不是完全释放它们。我不确定 valgrind 是否可以解决这个问题。

但我已经使用pthread_join. 我使用 VS2015 及其堆分析器。问题可能出在pthread我的特定实施中吗?我用的是宋东升的 PAL

导致内存泄漏:

Detected memory leaks!
Dumping objects ->
{104} normal block at 0x007742C0, 24 bytes long.
 Data: <     X          > D8 00 00 00 E0 58 20 00 00 00 00 00 00 00 00 00 
{101} normal block at 0x00774398, 24 bytes long.
 Data: <     X          > D8 00 00 00 E0 58 20 00 00 00 00 00 00 00 00 00 
{98} normal block at 0x00774038, 24 bytes long.
 Data: <     X          > D8 00 00 00 E0 58 20 00 00 00 00 00 00 00 00 00 
{95} normal block at 0x00774860, 24 bytes long.
 Data: <     X          > D8 00 00 00 E0 58 20 00 00 00 00 00 00 00 00 00 
Object dump complete.

每个 pthread 24 个字节。pthread_join()必须释放内存,但没有。所以我想实现是错误的。请确认或反驳这一点。

4

1 回答 1

1

如果您想跟踪分配点,请参阅_CrtSetAllocHook - 您可以设置自己的分配挂钩并检查堆栈中您知道将被泄露的块。但是,为了带来任何好处,您需要 POSIX 实现的调试版本才能正确查看堆栈。然后您可以尝试实际修补它,以便释放内存。

于 2016-12-09T10:40:55.767 回答