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

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

関連記事

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

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

C++のfork関数の構文や使い方について

  <目次> (1) C++のfork関数の構文や使い方について  (1-1) fork()関数とは?概要や目的  (1-2) fork()関数の構文  (1-3) fork()関数のサンプ …

パイプ通信とは?概要やサンプルプログラムをご紹介

  <目次> (1) パイプ通信とは?概要やサンプルプログラムをご紹介  (1-1) パイプ通信の概要  (1-2) パイプ通信の構文  (1-3) パイプ通信のサンプルプログラム①(単一プ …

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

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

C++で変数にアスタリスク(*)が2つ付いている意味について

  <目次> (1) C++で変数にアスタリスク(*)が2つ付いている意味について  (1-1) 変数にアスタリスク(*)が2つ付いている意味  (1-2) 構文  (1-3) サンプルプロ …

  • English (United States)
  • 日本語
Top