モーダルを閉じる工作HardwareHub ロゴ画像

工作HardwareHubは、ロボット工作や電子工作に関する情報やモノが行き交うコミュニティサイトです。さらに詳しく

利用規約プライバシーポリシー に同意したうえでログインしてください。

Valgrind による C/C++ メモリリーク検出

モーダルを閉じる

ステッカーを選択してください

お支払い手続きへ
モーダルを閉じる

お支払い内容をご確認ください

購入商品
」ステッカーの表示権
メッセージ
料金
(税込)
決済方法
GooglePayマーク
決済プラットフォーム
確認事項

利用規約をご確認のうえお支払いください

※カード情報はGoogleアカウント内に保存されます。本サイトやStripeには保存されません

※記事の執筆者は購入者のユーザー名を知ることができます

※購入後のキャンセルはできません

作成日作成日
2019/08/20
最終更新最終更新
2022/01/27
記事区分記事区分
一般公開

目次

    C/C++やアルゴリズムに注目し、実践的な知識を発信しています!

    JVM メモリリークでは JDK の jstat や jmap で原因を調査できます。C/C++ では valgrindMemcheck ツールが利用できます。valgrind には複数のツールが含まれており既定のツールが Memcheck です。他のツールを利用する場合は --tool オプションで指定します。

    簡単な利用例definitely lost

    必須ではありませんが -g -O0 オプションでコンパイルすると、valgrind の出力にファイル名および行番号が含まれるようになります。

    main.cpp

    #include <iostream>
    
    int main() {
        int* arr = new int[10];
        arr[10] = 1;
        return 0;
    }
    

    実行例

    g++ -Wall -O0 -g main.cpp
    valgrind --leak-check=yes a.out
    

    出力例

    ==21582== Memcheck, a memory error detector
    ==21582== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==21582== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
    ==21582== Command: a.out
    ==21582== 
    ==21582== Invalid write of size 4
    ==21582==    at 0x109173: main (main.cpp:5)
    ==21582==  Address 0x4d59ca8 is 0 bytes after a block of size 40 alloc'd
    ==21582==    at 0x483650F: operator new[](unsigned long) (vg_replace_malloc.c:423)
    ==21582==    by 0x109166: main (main.cpp:4)
    ==21582== 
    ==21582== 
    ==21582== HEAP SUMMARY:
    ==21582==     in use at exit: 40 bytes in 1 blocks
    ==21582==   total heap usage: 2 allocs, 1 frees, 72,744 bytes allocated
    ==21582== 
    ==21582== 40 bytes in 1 blocks are definitely lost in loss record 1 of 1
    ==21582==    at 0x483650F: operator new[](unsigned long) (vg_replace_malloc.c:423)
    ==21582==    by 0x109166: main (main.cpp:4)
    ==21582== 
    ==21582== LEAK SUMMARY:
    ==21582==    definitely lost: 40 bytes in 1 blocks
    ==21582==    indirectly lost: 0 bytes in 0 blocks
    ==21582==      possibly lost: 0 bytes in 0 blocks
    ==21582==    still reachable: 0 bytes in 0 blocks
    ==21582==         suppressed: 0 bytes in 0 blocks
    ==21582== 
    ==21582== For counts of detected and suppressed errors, rerun with: -v
    ==21582== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)
    
    • ==21582== → プロセス ID です。
    • Invalid write of size 4 → 無効なインデックス 10 arr[10] = 1 が指定されたことが検出されました。
    • definitely lostarr を free (delete) していないことが検出されました。

    indirectly lost

    メモリブロックへの参照 ptr->ptr は存在している場合であっても ptr 自体が lost してしまった場合は、結果として ptr->ptr で参照するメモリブロックは利用できなくなります。このような場合のメモリリークは indirectly lost として検出されます。

    #include <iostream>
    
    struct Node {
        Node* ptr;
    };
    
    int main() {
        Node* ptr = new Node();
        ptr->ptr = new Node();
        return 0;
    }
    

    出力例

    $ valgrind --leak-check=yes a.out
    ==27212== Memcheck, a memory error detector
    ==27212== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==27212== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
    ==27212== Command: a.out
    ==27212== 
    ==27212== 
    ==27212== HEAP SUMMARY:
    ==27212==     in use at exit: 16 bytes in 2 blocks
    ==27212==   total heap usage: 3 allocs, 1 frees, 72,720 bytes allocated
    ==27212== 
    ==27212== 16 (8 direct, 8 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2
    ==27212==    at 0x4835DEF: operator new(unsigned long) (vg_replace_malloc.c:334)
    ==27212==    by 0x109166: main (main.cpp:8)
    ==27212== 
    ==27212== LEAK SUMMARY:
    ==27212==    definitely lost: 8 bytes in 1 blocks
    ==27212==    indirectly lost: 8 bytes in 1 blocks
    ==27212==      possibly lost: 0 bytes in 0 blocks
    ==27212==    still reachable: 0 bytes in 0 blocks
    ==27212==         suppressed: 0 bytes in 0 blocks
    ==27212== 
    ==27212== For counts of detected and suppressed errors, rerun with: -v
    ==27212== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
    

    still reachable

    プログラムが終了する前に free/delete されなかった領域が存在する場合に still reachable と出力されます。プログラム自体が終了しているため definitely lost の場合と異なりメモリリークとして問題になることはありません。

    #include <iostream>
    
    int main() {
        int* arr = new int[10];
        exit(1);
        return 0;
    }
    

    出力例

    $ valgrind --leak-check=yes a.out
    ==27963== Memcheck, a memory error detector
    ==27963== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
    ==27963== Using Valgrind-3.14.0 and LibVEX; rerun with -h for copyright info
    ==27963== Command: a.out
    ==27963== 
    ==27963== 
    ==27963== HEAP SUMMARY:
    ==27963==     in use at exit: 40 bytes in 1 blocks
    ==27963==   total heap usage: 2 allocs, 1 frees, 72,744 bytes allocated
    ==27963== 
    ==27963== LEAK SUMMARY:
    ==27963==    definitely lost: 0 bytes in 0 blocks
    ==27963==    indirectly lost: 0 bytes in 0 blocks
    ==27963==      possibly lost: 0 bytes in 0 blocks
    ==27963==    still reachable: 40 bytes in 1 blocks
    ==27963==         suppressed: 0 bytes in 0 blocks
    ==27963== Reachable blocks (those to which a pointer was found) are not shown.
    ==27963== To see them, rerun with: --leak-check=full --show-leak-kinds=all
    ==27963== 
    ==27963== For counts of detected and suppressed errors, rerun with: -v
    ==27963== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0)
    
    Likeボタン(off)0
    詳細設定を開く/閉じる
    アカウント プロフィール画像

    C/C++やアルゴリズムに注目し、実践的な知識を発信しています!

    記事の執筆者にステッカーを贈る

    有益な情報に対するお礼として、またはコメント欄における質問への返答に対するお礼として、 記事の読者は、執筆者に有料のステッカーを贈ることができます。

    >>さらに詳しくステッカーを贈る
    ステッカーを贈る コンセプト画像

    Feedbacks

    Feedbacks コンセプト画像

      ログインするとコメントを投稿できます。

      ログインする

      関連記事