C言語,valgrindを使用してメモリリークを検出(確認)する

スポンサーリンク

鍛錬 429

C言語,valgrind を使用してメモリリークを検出(確認)する

プログラムのメモリリークを検出する方法の一つとして、valgrind を使用する方法があります。

関連記事:C言語,mtrace()を使用してメモリリークを検出(確認)する
 
使用方法は、以下に示す通りです。

valgrind --leak-check=full プログラム名

オプション

以下は、上記のオプションについてです。

オプション 機能
--leak-check=full 個別リークの詳細を表示する
スポンサーリンク

全体の流れ

以下は、valgrind でメモリリークを確認する際の大まかな流れです。

  1. gcc にオプションの -g を付加してコンパイルする。
  2. valgrind を実行する
  3. 解析結果を確認する。
スポンサーリンク

メモリリークしない場合の、valgrind の挙動を確認

まずは、メモリリークしない場合の valgrind の挙動について確認します。

プログラム(メモリリークしない場合)

以下は、malloc() でメモリを割り当てた後、free() でメモリを開放してメモリリークをさせないプログラム、test_valgrind.c です。

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

// main
int main(void)
{
	char *p;
	
	// メモリ割り当て
	p = (char *)malloc(256);
	
	// メモリ解放
	free(p);
	
	return 0;
}

実行結果

以下は、valgrind を使用してメモリリークの有無を確認しています。

[***@centos c]$ 
[***@centos c]$ gcc -g test_valgrind.c -o test_valgrind
[***@centos c]$ 
[***@centos c]$ 
[***@centos c]$ valgrind --leak-check=full ./test_valgrind
==12540== Memcheck, a memory error detector
==12540== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==12540== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==12540== Command: ./test_valgrind
==12540== 
==12540== 
==12540== HEAP SUMMARY:
==12540==     in use at exit: 0 bytes in 0 blocks
==12540==   total heap usage: 1 allocs, 1 frees, 256 bytes allocated
==12540== 
==12540== All heap blocks were freed -- no leaks are possible
==12540== 
==12540== For counts of detected and suppressed errors, rerun with: -v
==12540== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

 
上記に示した通り結果は、

==12540== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)

 
となり、メモリリークしていないことが確認できました。

スポンサーリンク

メモリリークする場合の、valgrind の挙動を確認

次に、メモリリークする場合の valgrind の挙動について確認します。

プログラム(メモリリークする場合)

以下は、malloc() でメモリを割り当てた後、free() でメモリを開放せずにメモリリークをさせているプログラム、test_valgrind.c です。

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

// main
int main(void)
{
	char *p;
	
	// メモリ割り当て
	p = (char *)malloc(256);
	
	// メモリ解放(今回はあえてリークさせるためコメントアウト)
//	free(p);
	(void)p;
	
	return 0;
}

実行結果

以下は、valgrind を使用してメモリリークの有無を確認しています。

[***@centos c]$ 
[***@centos c]$ gcc -g test_valgrind.c -o test_valgrind
[***@centos c]$ 
[***@centos c]$ 
[***@centos c]$ valgrind --leak-check=full ./test_valgrind
==12393== Memcheck, a memory error detector
==12393== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==12393== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==12393== Command: ./test_valgrind
==12393== 
==12393== 
==12393== HEAP SUMMARY:
==12393==     in use at exit: 256 bytes in 1 blocks
==12393==   total heap usage: 1 allocs, 0 frees, 256 bytes allocated
==12393== 
==12393== 256 bytes in 1 blocks are definitely lost in loss record 1 of 1
==12393==    at 0x4C29BC3: malloc (vg_replace_malloc.c:299)
==12393==    by 0x40052E: main (test_valgrind.c:11)
==12393== 
==12393== LEAK SUMMARY:
==12393==    definitely lost: 256 bytes in 1 blocks
==12393==    indirectly lost: 0 bytes in 0 blocks
==12393==      possibly lost: 0 bytes in 0 blocks
==12393==    still reachable: 0 bytes in 0 blocks
==12393==         suppressed: 0 bytes in 0 blocks
==12393== 
==12393== For counts of detected and suppressed errors, rerun with: -v
==12393== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

 
上記に示した通り結果は、

==12393== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

 
となり、メモリリークしていることが確認できました。

上記結果を詳しく見る

上記の結果について、

==12393== HEAP SUMMARY:
==12393==     in use at exit: 256 bytes in 1 blocks
==12393==   total heap usage: 1 allocs, 0 frees, 256 bytes allocated

 
と出力されているため、1つのメモリ割り当てに対し、0個の解放、つまり free をしていないことが確認できました。

またソースコード中の具体的な位置については、

==12393== 256 bytes in 1 blocks are definitely lost in loss record 1 of 1
==12393==    at 0x4C29BC3: malloc (vg_replace_malloc.c:299)
==12393==    by 0x40052E: main (test_valgrind.c:11)

 
と出力されているため、プログラム test_valgrind.c の 11 行目に記述されている、malloc() に対する free() が無いことが確認できました。

タイトルとURLをコピーしました