gpt4 book ai didi

c - Valgrind 检测到的 Still Reachable Leak

转载 作者:太空狗 更新时间:2023-10-29 16:14:20 29 4
gpt4 key购买 nike

此 block 中提到的所有函数都是库函数。我该如何纠正这种内存泄漏?

它列在“仍可访问”类别下。 (还有4个,很像,只是大小不一)

 630 bytes in 1 blocks are still reachable in loss record 5 of 5
at 0x4004F1B: calloc (vg_replace_malloc.c:418)
by 0x931CD2: _dl_new_object (dl-object.c:52)
by 0x92DD36: _dl_map_object_from_fd (dl-load.c:972)
by 0x92EFB6: _dl_map_object (dl-load.c:2251)
by 0x939F1B: dl_open_worker (dl-open.c:255)
by 0x935965: _dl_catch_error (dl-error.c:178)
by 0x9399C5: _dl_open (dl-open.c:584)
by 0xA64E31: do_dlopen (dl-libc.c:86)
by 0x935965: _dl_catch_error (dl-error.c:178)
by 0xA64FF4: __libc_dlopen_mode (dl-libc.c:47)
by 0xAE6086: pthread_cancel_init (unwind-forcedunwind.c:53)
by 0xAE61FC: _Unwind_ForcedUnwind (unwind-forcedunwind.c:126)

问题:一旦我运行我的程序,它就没有内存泄漏,但它在 Valgrind 输出中多了一行,这在以前是不存在的:

Discarding syms at 0x5296fa0-0x52af438 in /lib/libgcc_s-4.4.4-20100630.so.1 due to munmap()

如果无法纠正泄漏,有人可以至少解释为什么 munmap() 行导致 Valgrind 报告 0 个“仍然可访问”的泄漏吗?

编辑:

这是一个最小的测试样本:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>

void *runner(void *param) {
/* some operations ... */
pthread_exit(NULL);
}

int n;

int main(void) {

int i;
pthread_t *threadIdArray;

n=10; /* for example */

threadIdArray = malloc((n+n-1)*sizeof(pthread_t));

for(i=0;i<(n+n-1);i++) {
if( pthread_create(&threadIdArray[i],NULL,runner,NULL) != 0 ) {
printf("Couldn't create thread %d\n",i);
exit(1);
}
}


for(i=0;i<(n+n-1);i++) {
pthread_join(threadIdArray[i],NULL);
}

free(threadIdArray);

return(0);
}

运行:

valgrind -v --leak-check=full --show-reachable=yes ./a.out

最佳答案

定义“内存泄漏”的方法不止一种。特别是,“内存泄漏”有两个在程序员中普遍使用的主要定义。

“内存泄漏”的第一个常用定义是,“内存已分配但在程序终止前未随后释放”。然而,许多程序员(正确地)争辩说符合此定义的某些类型的内存泄漏实际上不会造成任何问题,因此不应被视为真实“内存泄漏”。

“内存泄漏”的一个可以说更严格(也更有用)的定义是,“内存已分配并且不能随后被释放,因为程序不再有任何指向已分配内存块的指针。”换句话说,您不能释放不再有任何指针指向的内存。因此,这样的内存是“内存泄漏”。 Valgrind 使用术语“内存泄漏”的这个更严格的定义。这种泄漏类型可能会导致显着的堆耗尽,尤其是对于长期存在的进程。

Valgrind 泄漏报告中的“仍可访问”类别是指仅符合“内存泄漏”的第一个定义的分配。这些 block 没有被释放,但它们本可以被释放(如果程序员愿意的话),因为程序仍在跟踪指向这些内存块的指针。

一般情况下,无需担心“仍可到达”的 block 。它们不会造成 真正 内存泄漏可能导致的那种问题。例如,“仍可到达”的 block 通常不会耗尽堆。这是因为这些 block 通常是一次性分配,在整个进程的生命周期中都会保留对它们的引用。虽然您可以通过并确保您的程序释放所有 分配的内存,但这样做通常没有实际好处,因为操作系统无论如何都会在进程终止后回收所有进程的内存。将此与 true 内存泄漏进行对比,内存泄漏如果不加以修复,可能会导致进程在运行时间足够长的情况下耗尽内存,或者只会导致进程消耗比必要更多的内存。

可能只有在您的泄漏检测工具无法判断哪些 block “仍然可以访问”(但 Valgrind 可以做到这一点)或者您的操作系统无法判断所有分配是否具有匹配的“释放”时才有用回收终止进程的所有内存(已移植 Valgrind 以执行此操作的所有平台)。

关于c - Valgrind 检测到的 Still Reachable Leak,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3840582/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com