0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Valgrindを使ってC言語のメモリリークを簡単にチェックしよう

Posted at

プログラミング言語Cで開発を行う際、プログラムのメモリ管理は非常に重要なポイントです。メモリの解放漏れ(メモリリーク)やアクセス違反は、予期せぬバグやクラッシュを引き起こす原因となります。これらの問題を未然に防ぐのに、valgrindは結構便利です。

Valgrindとは?

Valgrindは、プログラムのメモリ使用状況を解析するためのツールです。メモリリーク、アクセス違反、不正なメモリアクセスなどを検出し、詳細な情報をレポートとして出力してくれます。Linux系OS(Ubuntu, CentOS, Arch Linuxなど)で利用可能で、C/C++のデバッグには欠かせないツールの一つです。
僕も全然詳しくないですが、leaksコマンドが使えない環境でC言語を使う必要がある時、調べて見つけました。しかも使いこなせたら結構強そう

インストール方法

まずは、Valgrindをインストールしましょう。

sudo apt-get install valgrind

Valgrindの基本的な使い方

コマンドの概要

Valgrindを使ってプログラムの実行を追跡するためには、以下のコマンドを使用します。

valgrind [オプション] ./実行ファイル [引数]

よく使うオプション

  • --leak-check=full:メモリリークに関する詳細な情報を表示します。
  • --track-origins=yes:未初期化メモリの使用箇所を特定します。
  • --show-leak-kinds=all:全ての種類のメモリリーク(確保したが解放されていないメモリ、無効な解放など)を表示します。

これらのオプションを組み合わせて、メモリリークをチェックしてみましょう。

メモリリークのチェック方法

以下のようなメモリリークのある簡単なCプログラムを例にして、Valgrindを使ったメモリチェックを実行します。

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

void create_memory_leak() {
    int *leak = (int*) malloc(10 * sizeof(int));
    leak[0] = 42;
    // メモリを解放し忘れている
}

int main() {
    create_memory_leak();
    return 0;
}

上記のプログラムでは、mallocで確保したメモリがfreeされていないため、メモリリークが発生します。このプログラムをコンパイルし、Valgrindを使ってチェックしてみましょう。

gcc -g -o memory_leak_example memory_leak_example.c
valgrind --leak-check=full --track-origins=yes --show-leak-kinds=all ./memory_leak_example

出力結果の確認

Valgrindの出力結果を確認すると、以下のようなメッセージが表示されます。

==12345== Memcheck, a memory error detector
==12345== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==12345== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
==12345== Command: ./memory_leak_example
==12345==
==12345== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
==12345==    at 0x4C2B975: malloc (vg_replace_malloc.c:299)
==12345==    by 0x109156: create_memory_leak (memory_leak_example.c:6)
==12345==    by 0x109179: main (memory_leak_example.c:11)
==12345==
==12345== LEAK SUMMARY:
==12345==    definitely lost: 40 bytes in 1 blocks
==12345==    indirectly lost: 0 bytes in 0 blocks
==12345==      possibly lost: 0 bytes in 0 blocks
==12345==    still reachable: 0 bytes in 0 blocks
==12345==         suppressed: 0 bytes in 0 blocks
==12345==
==12345== For counts of detected and suppressed errors, rerun with: -v
==12345== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

出力の解釈

  • definitely lost は、確保したが解放されなかったメモリを指します。上記の例では、mallocで確保されたメモリ(40バイト分)が解放されずに失われていることが示されています。
  • at 0x4C2B975: malloc の部分は、メモリを確保した関数mallocの呼び出し元を特定しています。
  • by 0x109156: create_memory_leak は、create_memory_leak関数内のどの行でメモリを確保したか(memory_leak_example.c:6)を示しています。

メモリリークの修正

上記のプログラムを修正して、メモリリークを解消してみましょう。create_memory_leak関数にfreeを追加します。

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

void create_memory_leak() {
    int *leak = (int*) malloc(10 * sizeof(int));
    leak[0] = 42;
    free(leak);  // メモリを解放
}

int main() {
    create_memory_leak();
    return 0;
}

再度、コンパイルしてValgrindを実行します。

gcc -g -o memory_leak_example memory_leak_example.c
valgrind --leak-check=full --track-origins=yes --show-leak-kinds=all ./memory_leak_example

この修正版プログラムでは、メモリリークが解消され、Valgrindからのエラー出力も表示されません。

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

まとめ

C言語のメモリチェックには、valgrindを使うという手もあります。

valgrindを使う時は、--leak-check=full--track-origins=yes--show-leak-kinds=allのオプションが便利らしいです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?