3 4 Valgrind - ianchen0119/AwesomeCS GitHub Wiki

Memory Leak

考慮以下程式碼:

 #include <stdlib.h>

  void foo()
  {
     int* x = malloc(sizeof(int));
     // operations...
  }

  int main(void)
  {
     foo();
     for(;;){
     // ...
     }
     return 0;
  }

我們在 foo() 中呼叫了 Memory allocator ,這會在執行時分配動態記憶體空間供程式使用。以上面的範例來看,我們在使用後並沒有呼叫 free(x) 釋放已分配的記憶體,導致當 foo() 執行完成並跳回 main() 後,我們就遺失了指向這塊記憶體的指標 x ,造成記憶體洩漏的情況發生。

使用 Valgrind 檢測 Memory Leak

Valgrind is a suite of tools designed to provide debugging and profiling tools to make your programs more correct and detect some runtime issues. The most used of these tools is Memcheck, which can detect many memory-related errors that are common in C and C++ programs and that can lead to crashes and unpredictable behaviour (for example, unfreed memory buffers).

To run Valgrind on your program:

valgrind --leak-check=yes myprogram arg1 arg2

or

valgrind ./myprogram

Arguments are optional and the default tool that will run is Memcheck. The output will be presented in form of number of allocations, number of freed allocations, and the number of errors.

Example

Valgrind Example

Here's an example to help you interpret the above results. Suppose we have a simple program like this:

  #include <stdlib.h>

  void dummy_function()
  {
     int* x = malloc(10 * sizeof(int));
     x[10] = 0;        // error 1:as you can see here we write to an out of bound memory address
  }                    // error 2: memory leak the allocated x not freed

  int main(void)
  {
     dummy_function();
     return 0;
  }

Let's see what Valgrind will output (this program compiles and run with no errors).

==29515== Memcheck, a memory error detector
==29515== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==29515== Using Valgrind-3.11.0 and LibVEX; rerun with -h for copyright info
==29515== Command: ./a
==29515== 
==29515== Invalid write of size 4
==29515==    at 0x400544: dummy_function (in /home/rafi/projects/exocpp/a)
==29515==    by 0x40055A: main (in /home/rafi/projects/exocpp/a)
==29515==  Address 0x5203068 is 0 bytes after a block of size 40 alloc'd
==29515==    at 0x4C2DB8F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==29515==    by 0x400537: dummy_function (in /home/rafi/projects/exocpp/a)
==29515==    by 0x40055A: main (in /home/rafi/projects/exocpp/a)
==29515== 
==29515== 
==29515== HEAP SUMMARY:
==29515==     in use at exit: 40 bytes in 1 blocks
==29515==   total heap usage: 1 allocs, 0 frees, 40 bytes allocated
==29515== 
==29515== LEAK SUMMARY:
==29515==    definitely lost: 40 bytes in 1 blocks
==29515==    indirectly lost: 0 bytes in 0 blocks
==29515==      possibly lost: 0 bytes in 0 blocks
==29515==    still reachable: 0 bytes in 0 blocks
==29515==         suppressed: 0 bytes in 0 blocks
==29515== Rerun with --leak-check=full to see details of leaked memory
==29515== 
==29515== For counts of detected and suppressed errors, rerun with: -v
==29515== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

Invalid write: It detected our heap block overrun (writing outside of allocated block)

Definitely lost: Memory leak—you probably forgot to free a memory block

Valgrind is a very effective tool to check for errors at runtime. C is very special when it comes to such behavior, so after compiling your program you can use Valgrind to fix errors that your compiler may not catch and that usually happen when your program is running.

For more information, you can refer to the official website.

⚠️ **GitHub.com Fallback** ⚠️