绝对是C程序中丢失的内存泄漏

Pan*_*kos 6 c valgrind memory-leaks

有人能够阐明为什么Valgrind将这个程序归类为"绝对丢失:1个块中的2个字节"内存泄漏?我理解注释行解决了这个问题,但我不明白这个分类.根据Valgrind文档,似乎内存泄漏应归类为"间接可访问".我也很好奇为什么这甚至被认为是内存泄漏,并希望得到解释.即使程序在main函数结束时终止,手动释放所有内容也是一种好习惯吗?

#include <stdlib.h>

struct wrapper {
  char *data;
};

char *strdup(const char *);

struct wrapper *walloc(struct wrapper *root)
{
  if (root == NULL){
    root = (struct wrapper *) malloc(sizeof(struct wrapper));
    root->data = strdup("H");
  }

  return root;
}

int main(){
  struct wrapper *root;

  root = NULL;
  root = walloc(root);

  //free(root->data);

  return 0;
}
Run Code Online (Sandbox Code Playgroud)

这是Valgrind输出:

$ valgrind --leak-check=full ./leak
==26489== Memcheck, a memory error detector
==26489== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==26489== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==26489== Command: ./leak
==26489==
==26489==
==26489== HEAP SUMMARY:
==26489==     in use at exit: 2 bytes in 1 blocks
==26489==   total heap usage: 2 allocs, 1 frees, 1,790 bytes allocated
==26489==
==26489== 2 bytes in 1 blocks are definitely lost in loss record 1 of 1
==26489==    at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==26489==    by 0x4EB79C9: strdup (in /usr/lib/libc-2.20.so)
==26489==    by 0x400542: walloc (leak.c:13)
==26489==    by 0x400542: main (leak.c:23)
==26489==
==26489== LEAK SUMMARY:
==26489==    definitely lost: 2 bytes in 1 blocks
==26489==    indirectly lost: 0 bytes in 0 blocks
==26489==      possibly lost: 0 bytes in 0 blocks
==26489==    still reachable: 0 bytes in 0 blocks
==26489==         suppressed: 0 bytes in 0 blocks
==26489==
==26489== For counts of detected and suppressed errors, rerun with: -v
==26489== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Run Code Online (Sandbox Code Playgroud)

Pan*_*kos 2

感谢@sharth 为我指明了正确的方向。直接损失实际上被 Valgrind 正确检测到,但由于完全-O3删除的编译而令人困惑root。不使用编译-O3显示正确的直接丢失 8 个字节和间接丢失 2 个字节。

另外,感谢@SylvainL 和@Lundin 的最佳实践评论。

仅供参考:修正后的 Valgrind 输出如下所示:

==30492== Memcheck, a memory error detector
==30492== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==30492== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==30492== Command: ./leak
==30492==
==30492==
==30492== HEAP SUMMARY:
==30492==     in use at exit: 10 bytes in 2 blocks
==30492==   total heap usage: 3 allocs, 1 frees, 1,830 bytes allocated
==30492==
==30492== 10 (8 direct, 2 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2
==30492==    at 0x4C29F90: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==30492==    by 0x400687: walloc (leak.c:12)
==30492==    by 0x4006C6: main (leak.c:23)
==30492==
==30492== LEAK SUMMARY:
==30492==    definitely lost: 8 bytes in 1 blocks
==30492==    indirectly lost: 2 bytes in 1 blocks
==30492==      possibly lost: 0 bytes in 0 blocks
==30492==    still reachable: 0 bytes in 0 blocks
==30492==         suppressed: 0 bytes in 0 blocks
==30492==
==30492== For counts of detected and suppressed errors, rerun with: -v
==30492== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
Run Code Online (Sandbox Code Playgroud)