- PR -

new/deleteのエラーの原因がわかりません

1
投稿者投稿内容
piggest
会議室デビュー日: 2007/01/21
投稿数: 3
投稿日時: 2007-01-21 06:27
始めまして、piggestと申します。
半年前にVC++6.0を勉強し始めました。

deleteの際に出るエラーなのですが、どうしても原因がわからなくて質問をさせていただこうと来ました。
どうかよろしくお願いします。


ソースを全部書くのは読むほうとしても厄介かと思いますので要点のみを・・・
もし不足でしたら「そりゃあんたちゃんとこの部分も書いてくれんと」とつっこんでいただけると幸いです。
WindowsXpで、Debugモードの動作です。

//情報を覚える構造体
struct typMapParts{
float Height;
BYTE *Parts;//newで配列にして使用
BYTE Exisd;
BYTE Cursor;
};
void MapStruct::Reset()
{
int lMax;
struct typMapParts* mass;

lMax = size.x * size.y;
if(P!=NULL){
int i;
for(i=0; i<lMax; i++){
delete[] P[i].Parts;//☆
P[i].Parts=NULL;
}
delete[] P;
P=NULL;
}
if(Title!=NULL){
delete[] Title;
Title=NULL;
}
}

■コールスタック
_free_dbg_lk(void * 0x011b3280, int 1) line 1033 + 60 bytes
_free_dbg(void * 0x011b3280, int 1) line 970 + 13 bytes
operator delete(void * 0x011b3280) line 49 + 16 bytes
MapStruct::Reset() line 67 + 27 bytes

■メモリ
P[i].Parts = 0x011B3280
011B3260 A0 34 1B 01 30 32 1B 01 .4..02..
011B3268 00 00 00 00 00 00 00 00 ........
011B3270 2C 39 1B 01 01 00 00 00 ,9......
011B3278 D9 01 00 00 FD FD FD FD ル.......
011B3280 01 FD FD FD FD DD DD DD .....ンンン


メモリを見る限り、newで確保した領域(今回はBYTE[1])の前後に4バイトずつチェックバイトが正常にあるので、開放できるはず・・・と考えているのですが、これがエラーになります。
☆印の所のdeleteから入った_free_dbg_lkの中です。(下のコードの←印が実際にエラーになっているコードです)
(Title、P、sizeはメンバ変数それぞれLPSTR、struct typMapParts*(配列として使用)、xとyのメンバを持った構造体です。)

■_free_dbg_lk内のコード片
/* if we didn't already check entire heap, at least check this object */
if (!(_crtDbgFlag & _CRTDBG_CHECK_ALWAYS_DF))
{
/* check no-mans-land gaps */
if (!CheckBytes(pHead->gap, _bNoMansLandFill, nNoMansLandSize))
_RPT3(_CRT_ERROR, "DAMAGE: before %hs block (#%d) at 0x%08X.\n",
szBlockUseName[_BLOCK_TYPE(pHead->nBlockUse)],
pHead->lRequest,
(BYTE *) pbData(pHead));

if (!CheckBytes(pbData(pHead) + pHead->nDataSize, _bNoMansLandFill, nNoMansLandSize))
_RPT3(_CRT_ERROR, "DAMAGE: after %hs block (#%d) at 0x%08X.\n",
szBlockUseName[_BLOCK_TYPE(pHead->nBlockUse)],
pHead->lRequest,
(BYTE *) pbData(pHead));//←
}

■ウォッチ
pHead 0x011b3260
(BYTE *) pbData(pHead) CXX0017: Error: シンボル "pbData" が見つかりません


今までこういう場で質問をする事自体が初めてなので上手く書けていない事と思いますが、どうかよろしくお願いします。

[ メッセージ編集済み 編集者: piggest 編集日時 2007-01-21 06:27 ]
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-01-21 13:06
唐突に P やら p が出てきて、何がおかしいのかは分かりませんが

せっかく C++ を使ってるんですから、これ

引用:

//情報を覚える構造体
struct typMapParts{
float Height;
BYTE *Parts;//newで配列にして使用
BYTE Exisd;
BYTE Cursor;
};



こそクラスにして、動的なメモリ確保をコンストラクタ/デストラクタで行うのが良いんじゃないでしょうか。

てか、実はそれ以前に、本当に(自力での)動的なメモリ確保が必要なんでしょうか?

C++ 標準ライブラリの vector とかを使えばもっと楽に、件のような問題に突き当たることも無く先に進めるのではないかと思います。

未記入
大ベテラン
会議室デビュー日: 2005/03/12
投稿数: 148
投稿日時: 2007-01-21 13:44
具体的にどんなエラーのときどうしたらいいのか判らないので推測です。
確保し忘れとか初期化し忘れとかバッファオーバーランとかかな。
バッファオーバーランはすぐには気がつかないので厄介だよね。
別のC/MFCライブラリDLLまたはスタティックリンクするDLLがnew|deleteってことはないよね。
Kazuki
ぬし
会議室デビュー日: 2004/10/13
投稿数: 298
投稿日時: 2007-01-21 13:51
delete[]で実行時エラーが出るって事はnew[]してない所にdelete[]してるんじゃないですか?
コード:
struct Data
{
	char* Value;
};


int main(int argc, char* argv[])
{
	Data d;
	//d.Value = new char[10]; これがあると当然エラーにゃならない
	delete[] d.Value;
	return 0;
}



new[]してない所にdelete[]するとどう動くのかは忘れましたが
うちのVC++2005 ExpressだとDebugモードのときは実行時にDebug Error!っていうダイアログが出ました。
Releaseのときは何も出ません。
渋木宏明(ひどり)
ぬし
会議室デビュー日: 2004/01/14
投稿数: 1155
お住まい・勤務地: 東京
投稿日時: 2007-01-21 14:02
引用:

new[]してない所にdelete[]するとどう動くのかは忘れましたが



NULL ポインタに対する delete は、無害であると言語仕様で定義されています。

出鱈目なポインタ値を delete した場合の結果は、例によって保証されていません。
(VC++ の Debug ビルドなら何か情報を出すこともあるかもしれないですね)

piggest
会議室デビュー日: 2007/01/21
投稿数: 3
投稿日時: 2007-01-22 02:10
エラーメッセージの内容は下記の通りです

Debug Error!
Program: ...MapEditer.exe
DAMAGE:after Normal block (#473) at 0x011B3280

(Press Retry to debug application)


>渋木宏明(ひどり)様
はじめたばっかりで標準ライブラリなどを余り見ていませんでした。
vecterの使用を検討に入れて一度設計しなおしてみます。

>未記入様
ありがとうございます。
しかしメモリの表示で監視する限り、バッファーオーバーランと確保し忘れはなさそうなのです。
「スタティックリンクするDLLがnew|delete」というのはというのはどういうエラーなのでしょう??
そのことについてもう少し詳しく教えていただけると幸いです。

>Kazuki様
確保には2つの関数を用意しているのですが、両方ともnew BYTE[変数]であることを確認しました。

P[i].Parts はNULLポインタやでたらめなポインタである可能性についても調べてみましたが、原因は別のところにあるようです


返信くださった皆様本当にありがとうございます。
引き続きもう少し原因を探ってみる事にします。
甕星
ぬし
会議室デビュー日: 2003/03/07
投稿数: 1185
お住まい・勤務地: 湖の見える丘の上
投稿日時: 2007-01-22 11:27
引用:

piggestさんの書き込み (2007-01-22 02:10) より:
エラーメッセージの内容は下記の通りです

Debug Error!
Program: ...MapEditer.exe
DAMAGE:after Normal block (#473) at 0x011B3280

(Press Retry to debug application)


このメッセージから分かるのは、0x011B3280のヒープエリアの管理テーブルが壊されていると言う事だけです。その原因が貴方の提示した変数の付近にあるとは限りません。ヒープメモリに書き込む可能性のある全ての処理について検討する必要があります。

引用:

>未記入様
ありがとうございます。
しかしメモリの表示で監視する限り、バッファーオーバーランと確保し忘れはなさそうなのです。
「スタティックリンクするDLLがnew|delete」というのはというのはどういうエラーなのでしょう??
そのことについてもう少し詳しく教えていただけると幸いです。


例えばDLLをRelease版のVC++でビルドしていて、アプリケーションをDebug版でビルドしていたとします。DLL内で呼び出すnewはRelease版のnew、アプリケーション内で呼び出すdeleteはデバッグ版のdeleteになりますよね。Release版のnewとDebug版のdeleteは実装が異なるので、DLL内で確保したメモリをアプリケーション側で開放しようとするとエラーになります。これは異なるバージョンのVC++でビルドしたDLLとか、異なる言語でビルドしたDLLとかでも同様に当てはまります。
この場合の解決策としては、DLLとアプリケーションを同じバージョン&ビルドオプションでビルドするか、DLLないで確保したメモリはDLL内で開放するように実装するかいずれかです。
piggest
会議室デビュー日: 2007/01/21
投稿数: 3
投稿日時: 2007-01-23 00:48
>甕星様
管理テーブルについての知識がありませんでした。
実はあれから今回の件とは別のエラーを一つ直したのですが、それから今回のエラーが嘘のように消えてしまいました。
「こんなこともあるんだ・・・」と思っていたのですが、今の話を聞いて納得しました。
勉強になりました。

甕星様、また他の返信いただけた方、ありがとうございましたm(__)m
1

スキルアップ/キャリアアップ(JOB@IT)