为什么在线程退出时不会释放线程局部堆内存?

时间:2011-10-26 11:37:52

标签: c linux pthreads valgrind

参考这个结构,发布一个完整的例子会有点太大了:

__thread char* buf;
buf = malloc(1000);

Valgrind说这些字节“绝对”丢失了。他们不应该“仍然可以”到达吗?

5 个答案:

答案 0 :(得分:9)

因为分配的内存不是线程本地的。它由所有线程共享。

另一方面,变量是本地的线程,所以一旦它超出范围,分配的内存肯定会丢失(如果在其他地方没有该指针的副本......显然没有因为valgrind报告肯定丢失了)

你必须free

答案 1 :(得分:2)

您需要通过调用free显式释放它。

malloc分配的堆分配的内存在通过调用free明确释放之前不会被回收。当线程结束时,只有堆栈分配的本地存储对象会自动解除分配。

这肯定会丢失,因为一旦线程退出,你没有任何指向已分配内存的指针,指向内存的指针是线程堆栈的本地,当线程退出时它会被破坏,但是分配内存是堆内存,不会被解除分配。

答案 2 :(得分:2)

如果指向该块的唯一指针是线程本地的,那么通过退出该线程,您丢失了唯一的指针。

这意味着它不再可达=绝对丢失。

答案 3 :(得分:2)

好吧,正如其他人所说,你必须free

背后的原因是:所有线程共享一个公共堆,从概念上讲,内存“所有权”可以在线程之间传递。一个线程可以malloc一些东西,另一个可以释放它。但是,堆不知道谁拥有'内存,所以当你的线程终止时(即使堆记住了哪个线程malloc'd是什么),它无法安全地删除它。

但是,当进程终止时,所有堆内存都被有效地“释放” - 但不是单独的:您的进程的整个堆(可能只是一个大块)返回到操作系统。

答案 4 :(得分:0)

这有点像“味道好”/“少填充”的说法。 Valgrind是正确的,数据“仍然可以访问”。例如,如果数据包含密码,您可以100%从堆扫描中提取它们。如果数据以唯一的随机数开头,您可以重新定位它。 Valgrind意味着您无法再通过指针访问数据。