$ valgrind --tool=memcheck --leak-check=full ./main_c ==31416== Memcheck, a memory error detector ==31416== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==31416== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==31416== Command: ./main_c ==31416== ==31416== HEAP SUMMARY: ==31416== in use at exit: 4 bytes in 1 blocks ==31416== total heap usage: 1 allocs, 0 frees, 4 bytes allocated ==31416== ==31416== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==31416== at 0x4C2DBF6: malloc (vg_replace_malloc.c:299) ==31416== by 0x400537: main (main.c:5) ==31416== ==31416== LEAK SUMMARY: ==31416== definitely lost: 4 bytes in 1 blocks ==31416== indirectly lost: 0 bytes in 0 blocks ==31416== possibly lost: 0 bytes in 0 blocks ==31416== still reachable: 0 bytes in 0 blocks ==31416== suppressed: 0 bytes in 0 blocks ==31416== ==31416== For counts of detected and suppressed errors, rerun with: -v ==31416== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
==31416== 4 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==31416== at 0x4C2DBF6: malloc (vg_replace_malloc.c:299) ==31416== by 0x400537: main (main.c:5)
C++语言
Valgrind 也可以用来检测 C++ 程序的内存泄漏,下面是一个正常的 C++ 程序,没有发生内存泄漏:
1 2 3 4 5 6 7
#include<string> intmain() { auto ptr = new std::string("Hello, World!"); delete ptr; return0; }
$ valgrind --tool=memcheck --leak-check=full --show-leak-kinds=all ./main_cpp ==31438== Memcheck, a memory error detector ==31438== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==31438== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==31438== Command: ./main_cpp ==31438== ==31438== HEAP SUMMARY: ==31438== in use at exit: 72,704 bytes in 1 blocks ==31438== total heap usage: 2 allocs, 1 frees, 72,736 bytes allocated ==31438== ==31438== 72,704 bytes in 1 blocks are still reachable in loss record 1 of 1 ==31438== at 0x4C2DBF6: malloc (vg_replace_malloc.c:299) ==31438== by 0x4EC3EFF: ??? (in /usr/lib/x86_64-linux-gnu/libstdc++.so.6.0.21) ==31438== by 0x40104E9: call_init.part.0 (dl-init.c:72) ==31438== by 0x40105FA: call_init (dl-init.c:30) ==31438== by 0x40105FA: _dl_init (dl-init.c:120) ==31438== by 0x4000CF9: ??? (in /lib/x86_64-linux-gnu/ld-2.23.so) ==31438== ==31438== LEAK SUMMARY: ==31438== definitely lost: 0 bytes in 0 blocks ==31438== indirectly lost: 0 bytes in 0 blocks ==31438== possibly lost: 0 bytes in 0 blocks ==31438== still reachable: 72,704 bytes in 1 blocks ==31438== suppressed: 0 bytes in 0 blocks ==31438== ==31438== For counts of detected and suppressed errors, rerun with: -v ==31438== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
$ g++ -std=c++11 -g -o main_cpp main.cpp $ valgrind --tool=memcheck --leak-check=full ./main_cpp ==31523== Memcheck, a memory error detector ==31523== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==31523== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==31523== Command: ./main_cpp ==31523== ==31523== Invalid read of size 4 ==31523== at 0x400AD7: main (main.cpp:7) ==31523== Address 0x5ab5ca8 is 0 bytes after a block of size 40 alloc'd ==31523== at 0x4C2E216: operator new(unsigned long) (vg_replace_malloc.c:334) ==31523== by 0x4010D3: __gnu_cxx::new_allocator<int>::allocate(unsigned long, void const*) (new_allocator.h:104) ==31523== by 0x401040: std::allocator_traits<std::allocator<int> >::allocate(std::allocator<int>&, unsigned long) (alloc_traits.h:491) ==31523== by 0x400F91: std::_Vector_base<int, std::allocator<int> >::_M_allocate(unsigned long) (stl_vector.h:170) ==31523== by 0x400E7E: std::_Vector_base<int, std::allocator<int> >::_M_create_storage(unsigned long) (stl_vector.h:185) ==31523== by 0x400D1E: std::_Vector_base<int, std::allocator<int> >::_Vector_base(unsigned long, std::allocator<int> const&) (stl_vector.h:136) ==31523== by 0x400C11: std::vector<int, std::allocator<int> >::vector(unsigned long, int const&, std::allocator<int> const&) (stl_vector.h:291) ==31523== by 0x400AB9: main (main.cpp:6)
#include<iostream> intmain() { int x; if (x == 0) { std::cout << "X is zero" << std::endl; } return0; }
使用 Valgrind 检测这个程序:
1 2 3 4 5 6 7 8 9
$ g++ -std=c++11 -g -o main_cpp main.cpp $ valgrind --tool=memcheck --leak-check=full ./main_cpp ==31554== Memcheck, a memory error detector ==31554== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al. ==31554== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info ==31554== Command: ./main_cpp ==31554== ==31554== Conditional jump or move depends on uninitialised value(s) ==31554== at 0x400852: main (main.cpp:6)