【发布时间】:2011-12-15 16:01:39
【问题描述】:
参考这个结构,发布一个完整的例子有点太大了:
__thread char* buf;
buf = malloc(1000);
Valgrind 说字节“肯定”丢失了。他们不应该只是“仍然可以访问”吗?
【问题讨论】:
参考这个结构,发布一个完整的例子有点太大了:
__thread char* buf;
buf = malloc(1000);
Valgrind 说字节“肯定”丢失了。他们不应该只是“仍然可以访问”吗?
【问题讨论】:
因为分配的内存不是线程本地的。它由所有线程共享。
另一方面,该变量是线程本地的,因此一旦超出范围,分配的内存肯定会丢失(如果其他地方没有该指针的副本..显然没有,因为 valgrind 报告肯定会丢失)
你必须free它。
【讨论】:
malloc() 使用它。当引入线程时,很容易使用现有的功能。其次,每个线程实现一个堆意味着更多的 RAM 限制,并且可能在线程级别而不是进程级别进行交换。为什么不?但是这个特性能解决什么问题呢?允许悬空malloc()?实现垃圾收集器会更容易。
__thread 放在指针变量上会使malloc-obtained 块的无知的人,您将其地址存储在其中以某种方式线程本地...是否将auto 放在指针变量使malloc-obtained 块自动存储其地址(变量超出范围后立即释放)?哦对了,所有的本地变量默认都是auto...
如果指向块的唯一指针是线程本地的,那么退出线程,你就失去了唯一的指针。
这意味着它不再可达 = 肯定丢失了。
【讨论】:
您需要通过调用free 显式释放它。
由malloc 分配的堆分配内存在通过调用free 显式释放之前不会被回收。只有堆栈分配的本地存储对象会在线程结束时自动释放。
这肯定会丢失,因为一旦线程退出,您就没有任何指向分配内存的指针,指向内存的指针是线程堆栈的本地指针,当线程退出时它会被销毁,但是分配的内存是堆内存,不会被释放。
【讨论】:
好吧,正如其他人所说,你必须free它。
其背后的原因是:所有线程共享一个公共堆,并且从概念上讲,内存“所有权”可以在线程之间传递。一个线程可以 malloc 某些东西,而另一个线程可以释放它。但是,堆不知道谁“拥有”内存,所以当你的线程终止时(即使堆记得哪个线程 malloc 了什么)它不能安全地删除它。
但是,当你的 进程 终止时,所有的堆内存都被有效地“释放”了——但不是单独的:你的进程的整个堆(可能只是一个大块)被返回到操作系统。
【讨论】:
malloc 无法知道您要将其分配给线程本地指针。
这有点像“味道好”/“少饱”的说法。 Valgrind 是正确的,并且数据“仍然可以访问”。例如,如果数据包含密码,您可以 100% 从堆扫描中提取密码。如果数据以唯一的随机数开头,您可以重新定位它。 Valgrind 意味着你不能再通过指针访问数据。
【讨论】: