ヒープ破壊の原因がわからず困っています。

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
いもかん
記事: 2
登録日時: 5年前

ヒープ破壊の原因がわからず困っています。

#1

投稿記事 by いもかん » 5年前

タイトルの通り、DXライブラリを用いたゲームの制作中に遭遇したバグの原因がわかりません。
開発環境
OS:Windows7 32bit
コンパイラ:Microsoft Visual Studio 2010

プログラミングの経験は半年ほどです。

このプログラムは実行するとゲームのタイトル画面が現れます。
タイトル画面が表示されてすぐ終了すると正常終了になるのですが、タイトル画面でGAMESTARTを選んでゲーム画面に入ってから終了すると、以下のエラーメッセージが表示されます。


Windows によって DxLib_string.exe でブレークポイントが発生しました。

ヒープが壊れていることが原因として考えられます。DxLib_string.exe または読み込まれた DLL にバグがあります。

あるいは、DxLib_string.exe がフォーカスを持っているときに、ユーザーがF12 キーを押したことが原因として考えられます。

可能であれば、出力ウィンドウに詳細な診断情報が表示されます。


ゲーム画面に入らず終了した時はエラーは表示されなかったので、Scene_Menu.cpp内のEnemyMgr_Init();をコメントアウトしてみました。すると、今度はエラーメッセージが表示されなくなったので、私はEnemyMgr_Init()関数に原因があると考えています。
しかし、EnemyMgr_Init()関数や、それが書かれたEnemyMgr.cppなどのファイルを調べてみましたが、全く見当がつきません。

ファイルの数が多いので私が怪しいと思っているコードだけを貼っておきます。

情報が不足している、または文章がわかりづらいといった事があれば補足します。

main.cpp

コード:

#include"DxLib.h"
#include"KeyboardInput.h"
#include"SceneMgr.h"
#include"ExitMgr.h"
#include"Scene_Menu.h"
#include"PlayerMgr.h"
#include"Scene_Game.h"
#include"Scene_Pause.h"
#include"PlayerShotMgr.h"
#include"EnemyMgr.h"
#include"EnemyShotMgr.h"

int WINAPI WinMain( HINSTANCE hInstance , HINSTANCE hPrevInstance ,
	LPSTR lpCmdLine , int nCmdShow ){
		


		ChangeWindowMode(TRUE);

		if( DxLib_Init() == -1 ){
			exit( EXIT_FAILURE );
		}

		SetDrawScreen( DX_SCREEN_BACK );

		
		PlayerMgr_Load();

		PlayerShotMgr_Load();

		EnemyMgr_Load();

EnemyShotMgr_Load();

		//メインループ
		while( ProcessMessage() == 0 && ScreenFlip() == 0 && ClearDrawScreen() == 0 ){
			
			KeyboardMgr();

			switch( GetScene() ){
			case eScene_Menu:
				Menu();
				break;
			case eScene_Gamestart:
				
				if( Game_GetInitFlag() == 1 ){
					Game_Init();
					Game_SetInitFlag( 0 );
				}

				Game();
				break;
			case eScene_Quit:
				ReserveExit();
				break;
			case eScene_Pause:
				Pause();
				break;
			}


			
			if( GetExitFlag() == 1 ){
				break;
			}
			

			WaitTimer(16);

		}


//メモリ解放など
		PlayerMgr_End();
		PlayerShotMgr_End();
		EnemyMgr_End();
EnemyShotMgr_End();
		DxLib_End();

		return 0;
}
Scene_Game.cpp

コード:

#include"DxLib.h"
#include"Scene_Game.h"
#include"PlayerMgr.h"
#include"KeyboardInput.h"
#include"SceneMgr.h"
#include"PlayerMgr.h"
#include"PlayerShotMgr.h"
#include"EnemyMgr.h"
#include"EnemyShotMgr.h"

static int m_init_flag = 1;

void Game_Init(){

	PlayerMgr_Init();

	PlayerShotMgr_Init();

	EnemyMgr_Init();
	//ヒープ破壊の原因?

//EnemyShotMgr_Init();
//EnemyMgr_Init()を改変して作ったのでこちらでもヒープ破壊が起こる?

	return;

}

void Game(){

	if( GetKeyStateBuf( KEY_INPUT_P ) == 1 ){
		UpdateScene( eScene_Pause );
	}

	PlayerMgr_Update();

	PlayerShotMgr_Update();

	//未作成
//EnemyMgr_Update();
//EnemyShotMgr_Update();

	PlayerMgr_Draw();

	PlayerShotMgr_Draw();

	EnemyMgr_Draw();

	return;
}

void Game_SetInitFlag( int iFlag ){

	m_init_flag = iFlag;

	return;
}

int Game_GetInitFlag(){

	return m_init_flag;
}
EnemyMgr.cpp

コード:

#include"DxLib.h"
#include"EnemyMgr.h"
#include"Typedef_HitCheck.h"
#include<stdlib.h>

static int m_enemyVariety;
static enemyData_t * m_data;
static enemy_t ** m_enemy;
static position_t ** m_position;

void EnemyMgr_Load(){

	int i , k;

	m_enemyVariety = 1;

	m_data = ( enemyData_t * ) malloc( sizeof( enemyData_t ) * m_enemyVariety );

	m_enemy = ( enemy_t ** ) malloc( sizeof( enemy_t * ) * m_enemyVariety );
	
	m_position = ( position_t ** ) malloc( sizeof( position_t * ) * m_enemyVariety );

	if( ( m_data == NULL ) ||
		( m_enemy == NULL ) ||
		( m_position == NULL ) ){

			DxLib_End();
			exit( EXIT_FAILURE );
	}

	EnemyMgr_LoadData();
	
	
	for( i = 0 ; i < m_enemyVariety ; i++ ){
		
		m_enemy[i] = ( enemy_t * ) malloc( sizeof( enemy_t * ) * m_data[i].max );
		
		m_position[i] = ( position_t * ) malloc( sizeof( position_t * ) * m_data[i].max );
		if( ( m_enemy[i] == NULL ) ||
			( m_position[i] == NULL ) ){

				DxLib_End();
				exit( EXIT_FAILURE );
		}

	}

	return;
}

void EnemyMgr_LoadGraph(){

	int i;

	for( i = 0 ; i < m_enemyVariety ; i++ ){

		LoadDivGraph( "images/testE.png" , m_data[i].graphNum , m_data[i].graphNumX , m_data[i].graphNumY
				, m_data[i].graphSizeX , m_data[i].graphSizeY , m_data[i].graph );

	}


	return;
}

void EnemyMgr_LoadData(){

	int i;

	for( i = 0 ; i < m_enemyVariety ; i++ ){

		m_data[i].hit = ( hitData_t * ) malloc( sizeof( hitData_t ) );
		m_data[i].hit->type = RECTANGLE;
		m_data[i].hit->area.rect.start.x = 0;
		m_data[i].hit->area.rect.start.y = 0;
		m_data[i].hit->area.rect.width = 192;
		m_data[i].hit->area.rect.height = 128;

		m_data[i].graphNum = 2;
		m_data[i].graphNumX = 1;
		m_data[i].graphNumY = 2;
		m_data[i].graphSizeX = 192;
		m_data[i].graphSizeY = 128;

		m_data[i].max = 2;
		m_data[i].maxhp = 4;

		m_data[i].graph = ( int * ) malloc( sizeof( int ) * m_data[i].graphNum );
		
		if( m_data[i].graph == NULL ){

			DxLib_End();
			exit( EXIT_FAILURE );
		}


	}

	EnemyMgr_LoadGraph();

	return;
}

void EnemyMgr_Init(){
	int i , k;

	for( i = 0 ; i < m_enemyVariety ; i++ ){
		for( k = 0 ; k < m_data[i].max ; k++ ){
			m_position[i][k].x = k * 200;
			m_position[i][k].y = 0;
			m_enemy[i][k].flag = 1;
			m_enemy[i][k].currentgraph = 0;
			m_enemy[i][k].hp = m_data[i].maxhp;
			m_enemy[i][k].state = 0;
		}

	}
	

	return;
}

void EnemyMgr_Update();

void EnemyMgr_Draw(){
	
	int i , k;
	for( i = 0 ; i < m_enemyVariety ; i++ ){
		for( k = 0 ; k < m_data[i].max ; k++ ){

			if( m_enemy[i][k].flag == 1 ){

				DrawGraph( m_position[i][k].x, m_position[i][k].y 
					, m_data[i].graph[m_enemy[i][k].currentgraph] , TRUE );

			}

		}
	}


	return;
}

void EnemyMgr_End(){

	int i;
	
	for( i = 0 ; i < m_enemyVariety ; i++ ){
	
		if( m_data[i].graph != NULL ){
			free( m_data[i].graph );
			m_data[i].graph = NULL;
		}
		if( m_data[i].hit != NULL ){
			free( m_data[i].hit );
			m_data[i].hit = NULL;
		}
		if( m_enemy[i] != NULL ){
			free( m_enemy[i] );
			m_enemy[i] = NULL;
		}
		if( m_position[i] != NULL ){
			free( m_position[i] );
			m_position[i] = NULL;
		}

	}
	
	if( m_data != NULL ){
		free( m_data );
		m_data = NULL;
	}
	if( m_enemy != NULL ){
		free( m_enemy );
		m_enemy = NULL;
	}
	if( m_position != NULL ){
		free( m_position );
		m_position = NULL;
	}

	return;
}
EnemyMgr.h

コード:

#ifndef DEF_ENEMYMGR_H

#define DEF_ENEMYMGR_H

struct hitData;
struct position;

typedef struct{
	struct hitData * hit;
	int graphNum , graphNumX , graphNumY;
	int graphSizeX , graphSizeY;
	int *graph;
	int maxhp;
	int max;
}enemyData_t;

typedef struct{
	int currentgraph;
	int flag;
	int hp;
	int state;
}enemy_t;



void EnemyMgr_Load();

void EnemyMgr_LoadData();

void EnemyMgr_LoadGraph();

void EnemyMgr_Init();

void EnemyMgr_Update();

void EnemyMgr_Draw();

void EnemyMgr_End();

#endif
Typedef_HitCheck.h

コード:

#ifndef TYPEDEF_HITCHECK_H

#define TYPEDEF_HITCHECK_H

typedef struct position{
	float x;
	float y;
}position_t;

typedef position_t vector_t;

typedef struct rectangle{
	position_t start;
	int width;
	int height;
}rectangle_t;

typedef struct circle{
	position_t center;
	int radius;
}circle_t;

typedef union hitArea{
	rectangle_t rect;
	circle_t circ;
}hitArea_t;

typedef enum hitType{
	RECTANGLE,
	CIRCLE,
}hitType_t;

typedef struct hitData{
	hitType_t type;
	hitArea_t area;
}hitData_t;

#endif

jay
記事: 314
登録日時: 9年前
住所: 大阪市
連絡を取る:

Re: ヒープ破壊の原因がわからず困っています。

#2

投稿記事 by jay » 5年前

それじゃあブレークポイントを仕込んで
EnemyMgr_Init()をステップ実行してみると原因が分かるかもしれません。
♪僕たちは まだ森の中 抜け出そう 陽のあたる場所へ

いもかん
記事: 2
登録日時: 5年前

Re: ヒープ破壊の原因がわからず困っています。

#3

投稿記事 by いもかん » 5年前

jayさん、返信ありがとうございます。おかげさまで原因を突き止めることができました。

EnemyMgr_Init()にブレークポイントを仕込んでも何も起きませんでしたが、EnemyMgr_End()にブレークポイントを仕込んだら、Enemyを開放したところでエラーメッセージが表示されました。

EnemyMgr_Load()関数内で確保したメモリのサイズが間違っていたことが原因だったようです。

もとのコードでは

m_enemy = ( enemy_t * ) malloc( sizeof( enemy_t * ) * m_data.max );

となっていましたが、正しくは

m_enemy = ( enemy_t * ) malloc( sizeof( enemy_t ) * m_data.max );

と書かなければなりませんでした。また、m_positionにアドレスを格納したメモリのサイズも同じように間違っていました。

閉鎖

“C言語何でも質問掲示板” へ戻る