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

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

関連記事

Valgrindで行番号を表示させる方法

  <目次> (1) Valgrindで行番号を表示させる方法  (1-1) 行番号を表示させる方法  (1-2) (参考)「-g」オプションについて (1) Valgrindで行番号を表示 …

Valgrindの使い方や見方について(基礎編)

  <目次> (1) Valgrindの使い方や見方について(基礎編)  (1-1) メモリリークのチェックのやり方  (1-2) 「valgrind」コマンドの基本的な使い方  (1-3) …

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

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

C++のtime関数とlocaltime関数の違いについて

  <目次> (1) C++のtime関数とlocaltime関数の違いについて  (1-1) C++のlocaltime関数の概要とサンプル  (1-2) C++のtime関数の概要とサン …

C++の共用体とは?構造体との違いや使用方法について

  <目次> (1) C++の共用体とは?構造体との違いや使用方法について  (1-1) 共用体とは?構造体との違いは?  (1-2) 共用体の定義方法、変数定義方法、初期化方法  (1-3 …

  • English (United States)
  • 日本語
Top