Rainbow Engine

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

C++

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

投稿日:2022年2月26日 更新日:

 

<目次>

(1) C++で発生した「 _CrtIsValidHeapPointer(block)」と「is_block_type_valid(header->_block_use)」エラーについて
 (1-1) 事象・発生状況
 (1-2) 原因
 (1-3) 対策
 (1-4) 参考

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

本記事ではC++で発生した「 _CrtIsValidHeapPointer(block)」と「is_block_type_valid(header->_block_use)」エラーについてご紹介します。

(1-1) 事象・発生状況

C++のプログラムを実行した結果、以下のエラーが発生しました。

●エラーメッセージ

Debug Assertion Failed!

Program:
XXXX
Line XXX

Expression: _CrtIsValidHeapPointer(block)

(図111)

Debug Assertion Failed!

Program:
XXXX
Line XXX

Expression: is_block_type_valid(header->_block_use)

(図112)

●事象発生のサンプルプログラム

 
上記のエラーを再現するためのサンプルプログラムをご紹介します。
#include <iostream>
using namespace std;
int main(void) {

    int n1 = 10;
    int* n1p = &n1;
    delete[] n1p;

}

目次にもどる

(1-2) 原因

下記の原因が考えられます。

●メッセージ「_CrtIsValidHeapPointer」の原因

・解放されるべきポインタが既に有効でない(or正しくない)場合

(発生例)「new」していないのに「delete[]」している場合
    int n1 = 10;
    int* n1p = &n1;
    delete[] n1p;

●メッセージ「is_block_type_valid(header->_block_use)」の原因

・こちらもメモリの使用や解放に関連しているケースが多く、例えば同じアドレスブロックを繰り返し削除した場合などに発生する様です。

(発生例)「new」していないのに「delete」している場合
    int n1 = 10;
    int* n1p = &n1;
    delete n1p;

目次にもどる

(1-3) 対策

上記の発生例の場合、対策としては「delete」対応する「new」の定義を設ける事で解決する事ができます。

(例)
    int* n1p = new int;
    n1p[0] = 10;
    delete n1p;
(図131)

なので、チェックする観点の例としては以下の通りです。
①「delete」しているのに「new」されていない箇所が無いかを確認する
②「new」に対しては「delete」で解放になっているかを確認する
③「new 型[N]」に対しては「delete[]」で解放になっているか確認する

目次にもどる

(1-4) 参考

●参考1

ちなみに、上記の②と③のケースはエラーではなく、下図のような警告になるようです。単一の非配列オブジェクトの場合は「new」と「delete」で、逆に配列オブジェクトの場合は「new []」と「delete[]」を使います。

・②がNGの例
⇒「new」に対して「delete[]」で解放している
 
・③がNGの例
⇒「new []」に対して「delete」で解放している

●参考2:②と③のNGで起きている事

「new[]」で返却されるポインタは常に割当てされたメモリの先頭を見るとは限りません。なぜなら、動的にメモリを割り当てる際は、その「サイズ」の情報を「先頭」に保持するため、その分だけオフセット(補正)されてしまい、先頭はサイズの情報となるためです。
 
int* n1p = new int[10];

 

例えば、下記のポインタ定義では要素を10つ確保していますが、このポインタのサイズ(要素10個)の情報を保持するため、先頭は1要素目のデータではなく、サイズになります。なので、ここで通常「delete[]」とすべき所を「delete」としてしまうと、そのオフセット分がミスマッチとなり警告に繋がっているようです。
 
 

Adsense審査用広告コード


Adsense審査用広告コード


-C++

執筆者:


comment

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

関連記事

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

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

C++のマルチスレッド処理のサンプルや概要について

  <目次> (1) C++のマルチスレッド処理のサンプルや概要について  (1-1) C++のマルチスレッドの概要  (1-2) 構文1:関数ポインタ式  (1-3) 構文1(例):関数ポ …

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

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

C++の値渡しと参照渡しの使い分けや違いについて

<目次> (1) C++の値渡しと参照渡しの使い分けや違いについて  (1-1) 「値渡し」とは?  (1-2) 「参照渡し」とは?  (1-3) 「値渡し」と「参照渡し」の使い分け (1) C++の …

C++のunsigned char型とは?概要やsigned charとの違いもご紹介

<目次> (1) C++のunsigned char型とは?概要やsigned charとの違いもご紹介  (1-1) 概要  (1-2) サンプルプログラム①:疎通確認 (1) C++のunsign …

  • English (United States)
  • 日本語
Top