Valgrind肯定输了,并且在退出vs主要回归时可以到达

时间:2015-07-25 03:59:24

标签: c valgrind

如果我使用return 0;退出main,Valgrind报告肯定会丢失内存,但如果我使用exit(0);退出main,则报告仍然可以访问内存。

测试reachable.c:

#include <stdlib.h>

int main() {
  void *data = malloc(256);
  exit(0);
}

测试lost.c:

#include <stdlib.h>

int main() {
  void *data = malloc(256);
  return 0;
}

行为:

$ gcc test-reachable.c -o test-reachable
$ valgrind --leak-check=yes ./test-reachable
==7696== Memcheck, a memory error detector
==7696== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7696== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==7696== Command: ./test-reachable
==7696== 
==7696== 
==7696== HEAP SUMMARY:
==7696==     in use at exit: 256 bytes in 1 blocks
==7696==   total heap usage: 1 allocs, 0 frees, 256 bytes allocated
==7696== 
==7696== LEAK SUMMARY:
==7696==    definitely lost: 0 bytes in 0 blocks
==7696==    indirectly lost: 0 bytes in 0 blocks
==7696==      possibly lost: 0 bytes in 0 blocks
==7696==    still reachable: 256 bytes in 1 blocks
==7696==         suppressed: 0 bytes in 0 blocks
==7696== Reachable blocks (those to which a pointer was found) are not shown.
==7696== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==7696== 
==7696== For counts of detected and suppressed errors, rerun with: -v
==7696== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$ gcc test-lost.c -o test-lost
$ valgrind --leak-check=yes ./test-lost
==7774== Memcheck, a memory error detector
==7774== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==7774== Using Valgrind-3.10.1 and LibVEX; rerun with -h for copyright info
==7774== Command: ./test-lost
==7774== 
==7774== 
==7774== HEAP SUMMARY:
==7774==     in use at exit: 256 bytes in 1 blocks
==7774==   total heap usage: 1 allocs, 0 frees, 256 bytes allocated
==7774== 
==7774== 256 bytes in 1 blocks are definitely lost in loss record 1 of 1
==7774==    at 0x4C2C080: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==7774==    by 0x40051C: main (in /tmp/test-lost)
==7774== 
==7774== LEAK SUMMARY:
==7774==    definitely lost: 256 bytes in 1 blocks
==7774==    indirectly lost: 0 bytes in 0 blocks
==7774==      possibly lost: 0 bytes in 0 blocks
==7774==    still reachable: 0 bytes in 0 blocks
==7774==         suppressed: 0 bytes in 0 blocks
==7774== 
==7774== For counts of detected and suppressed errors, rerun with: -v
==7774== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

这些行为不一样吗?

2 个答案:

答案 0 :(得分:3)

  

这些行为不应该相同吗?

没有

在test-reachable.c中,在程序退出时,堆栈变量data引用内存,因此它仍然可以访问,而在test-lost.c中,内存未被引用因为main函数已经返回,引用不再存在,内存肯定会丢失。

答案 1 :(得分:2)

在C ++中,当调用return中的main()时,将为本地范围的对象调用析构函数,而如果调用exit(),则不会为本地作用域的对象调用析构函数。 我认为在C中关于堆栈上分配的对象的情况类似。

这可能解释了为什么在return情况下,非释放内存被视为绝对丢失,而在exit(0)情况下,内存被报告为仍然可以访问。