Rainbow Engine

IT技術を分かりやすく簡潔にまとめることによる学習の効率化、また日常の気付きを記録に残すことを目指します。

C++

ValgrindのPossibly Lostの意味や実際のサンプルをご紹介

投稿日:2021年10月26日 更新日:

 

<目次>

(1) ValgrindのPossibly Lostの意味や実際のサンプルをご紹介
 (1-1) Valgrindの「Possibly Lost」はどんな状況?
 (1-2) 例1:サンプルプログラム
 (1-3) 例1:Valgrindのメモリリーク確認結果

(1) ValgrindのPossibly Lostの意味や実際のサンプルをご紹介

本記事ではValgrindにおけるメモリリークのカテゴリの1つである「Possibly Lost」についてご紹介します。

(1-1) Valgrindの「Possibly Lost」はどんな状況?

「still reachable」と同様に、まだメモリへのポインタが残っているものの、配列等の割り当てされたメモリの「中央」の値を指しており(interior-pointer)、始点を指すポインタ(start-pointer)が消失している状態です。
 
「Possibly」(おそらく)という単語からも想像が付きますが、このステータスはValgrind側でも確実なメモリリーク(Definetely Lost)か?そうでないか(Still Reachable)は判断がつかないグレーな状況と言えます。なので、この結果を受けての詳細な確認(Definetely Lostなのか?Still Reachableなのか?)するのはプログラマのタスクとなります。
 
例えば次のような要素が3つのint型の配列を「int i* = new int[3]」で定義します(参考:動的メモリ確保)。この時、ポインタ「i*」は配列の最初の要素のアドレス、つまりi[0]のアドレスを指しています。
 
一方でグローバル変数として定義しているポインタ「x1*」には「x1 = i+2;」で配列の3要素目のアドレスを代入すると、x1としては配列の最初の要素のアドレスが分からず(最初の要素へのポインタが無い)、2番目以降の途中の要素を指示したポインタとなります(Valgrindではこのような状況を「interior-pointer」と呼んでいるようです)。このような状況下で「possibly lost」が発生します。
 
(図111)

(1-2) 例1:サンプルプログラム

前述の(図111)の状況を実際に再現したのが次の(例1)のサンプルプログラムです。
 
(例1)
#include <stdlib.h>

int *x1;

int main(void)
{
    //# int型の配列(4要素)を動的に確保
    int *i = new int[4];
    //# 配列の各要素に値を格納
    i[0] = 10;
    i[1] = 11;
    i[2] = 12;
    i[3] = 13;
    //# グローバル変数のポインタ「*x1」のアドレスに、iの2要素先
    //# つまり配列の3要素目のアドレスを代入する
    x1 = i+2;

    return 0;
}
(図121)

(1-3) 例1:Valgrindのメモリリーク確認結果

上記のサンプルプログラムをコンパイルし、valgrindコマンドでメモリリークチェック(⇒★)を実行した際の出力結果をご紹介します。
 
(出力サンプル)
==2374== HEAP SUMMARY:
==2374==     in use at exit: 16 bytes in 1 blocks
==2374==   total heap usage: 1 allocs, 0 frees, 16 bytes allocated
==2374==
==2374== 16 bytes in 1 blocks are possibly lost in loss record 1 of 1
==2374==    at 0x4C2C866: operator new[](unsigned long) (vg_replace_malloc.c:579)
==2374==    by 0x40059E: main (memorytest_possibly.cpp:7)
==2374==
==2374== LEAK SUMMARY:
==2374==    definitely lost: 0 bytes in 0 blocks
==2374==    indirectly lost: 0 bytes in 0 blocks
==2374==      possibly lost: 16 bytes in 1 blocks
==2374==    still reachable: 0 bytes in 0 blocks
==2374==         suppressed: 0 bytes in 0 blocks
==2374==
==2374== For lists of detected and suppressed errors, rerun with: -s
==2374== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
(図131)
(参考)
Possibly Lostを結果に表示したくない場合は、valgrindコマンドで「–show-possibly-lost=no」オプションを指定する事で非表示にする事ができます。
 
(例)
valgrind --tool=memcheck --leak-check=yes --show-possibly-lost=no ../チェック対象プログラム

Adsense審査用広告コード


Adsense審査用広告コード


-C++

執筆者:


comment

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です

関連記事

C++のポインタとは?概念や基本的な使い方をご紹介

  <目次> (1) C++のポインタとは?概念や基本的な使い方をご紹介  (1-1) はじめに  (1-2) ポインタとは? (1) C++のポインタとは?概念や基本的な使い方をご紹介 「 …

C++で「静的でないメンバー参照は特定のオブジェクトを基準とする相対参照である必要があります」エラーが出た時の対処

  <目次> (1) C++で「静的でないメンバー参照は特定のオブジェクトを基準とする相対参照である必要があります」エラーが出た時の対処  (1-1) エラーメッセージ  (1-2) 原因 …

C++のlocaltime関数がスレッドアンセーフである理由と使用上の注意点

  <目次> (1) C++のlocaltime関数がスレッドアンセーフである理由と使用上の注意点  (1-1) localtime関数がスレッドアンセーフである理由  (1-2) loca …

C++の「int **g = new int*;」の意味について

  <目次> (1) C++の「int **g = new int*;」の意味について  (1-1) 「int **g = new int*;」の意味  (1-2) サンプルで理解を深める …

C++のtime関数やtime_t型の使い方について

  <目次> (1) C++のtime関数やtime_t型の使い方について  (1-1) C++のtime関数とtime_t型とは?  (1-2) C++のtime_t関数のサンプル (1) …

  • English (United States)
  • 日本語
Top