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-3) …

CORBA通信のPOA(Portable Object Adapter)とは?

  <目次> (1) CORBA通信のPOA(Portable Object Adapter)とは?  (1-1) 概要と特徴  (1-2) 一般的なPOAの処理構成  (1-3) POAの …

C++で発生した「 _CrtIsValidHeapPointer(block)」と「is_block_type_valid(header->_block_use)」エラーについて

  <目次> (1) C++で発生した「 _CrtIsValidHeapPointer(block)」と「is_block_type_valid(header->_block_use) …

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

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

ポインタと参照の違いについてサンプルPGを使ってご紹介

  <目次> (1) ポインタと参照の違いについてサンプルPGを使ってご紹介  (1-1) ポインタと参照の概要  (1-2) 両者の違い①:宣言/初期化  (1-3) 両者の違い②:再代入 …

  • English (United States)
  • 日本語
Top