ウィンドウを閉じた後のアクセス違反

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

ウィンドウを閉じた後のアクセス違反

#1

投稿記事 by もるも » 8年前

こんにちは。

デバッグをやめるときに、ウィンドウを閉じて終了しようとすると
DxLib_End()でアクセス違反が起こってしまいます。

ウィンドウを閉じるときの出力はこんな感じです。
============================================
2260:ウインドウが破棄されようとしています
2262:ソフトを終了する準備が整いました
2273:d3d11.dll の解放 1
'ActionRPG.exe' (Win32): 'C:\Windows\SysWOW64\d3d11.dll' がアンロードされました
2276:dxgi.dll の解放 1
'ActionRPG.exe' (Win32): 'C:\Windows\SysWOW64\dxgi.dll' がアンロードされました
2277:Direct3D11 のオブジェクト数を出力
2278:ID3D11Texture2D : 1
2279:ID3D11ShaderResourceView : 1
2279:Direct3D11 のオブジェクト合計数 : 2
0x0078B21F で例外がスローされました (ActionRPG.exe 内): 0xC0000005: 場所 0x6B577938 の読み取り中にアクセス違反が発生しました
============================================
呼び出し履歴では
ActionRPG.exe!DxLib::Direct3D11_Release_ShaderResourceView(class D_ID3D11ShaderResourceView *) C++
というところで黄色い→が止まっています。

この症状がでるのが今作っているゲームだけです。
呼び出し履歴などを見ても自分ではどこが悪いのかどうなおせばいいのか見当がつかず困っています。

Windows10
VisualStudio 2015(C++)を使用しています。

よろしくお願いします。

アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: ウィンドウを閉じた後のアクセス違反

#2

投稿記事 by へにっくす » 8年前

ログを見る限りでは、dllの解放のあと、オブジェクト数が0になってませんよね。
C/C++言語は、確保したメモリはプログラム終了時に責任もって自分で解放する必要があります。
それと同じで自分で作成したオブジェクトは、自分で削除する必要があるのです。ログはそのことを多分ですが、示しています。
基本、Create~の関数のAPIがあったら、それとは逆のDelete~かRelease~という関数があるはずです。
ソースが掲示されていないので具体的なアドバイスができませんが、言えることはこれくらいですね。

一番良いのは、現象が起きる最小限のコードを掲示するか、それが面倒であればプロジェクト一式をzipに固めてアップロードしてください。
(zipに固める場合はソースファイルだけにすることを忘れずに。でないとサイズ制限でアップロードできません)
そうすれば詳しい人が(いたら)見てくれますよ。
written by へにっくす

naohiro19
記事: 256
登録日時: 13年前
住所: 愛知県

Re: ウィンドウを閉じた後のアクセス違反

#3

投稿記事 by naohiro19 » 8年前

へにっくすさんの説明を補足すると「メモリリーク」していますね。

アバター
もるも
記事: 54
登録日時: 8年前
連絡を取る:

Re: ウィンドウを閉じた後のアクセス違反

#4

投稿記事 by もるも » 8年前

>へにっくすさん
回答ありがとうございます。
プログラム終了時はメモリを一気に解放してくれるから大丈夫だろうという考えを持っていました(><)

> naohiro19さん
補足ありがとうございます。
===============================================
途中経過の報告をします。
Controlクラスで一気にオブジェクトを管理しているのですが、
Itemクラスのオブジェクトを生成すると起こるところまでわかりました。
どこから探せばいいか分からず、
メモリリーク探しに時間がかかりそうです・・・。

コード:

Control::Control(){
	//グラフィック
	LoadDivGraph("media/ItemIconGraphics.png",36,9,4,32,32,item_gh);

//==================================================================
//new
//==================================================================
	player=new PlayerChara(item_gh);

	for(int i=0;i<=ENEMY_NUM;i++){
		enemy[i] = new Enemy(320 + 32 * i, 320, type[i], 0, 200, true, NULL,NULL);
	}
	
	hours24 = new Hours24();
	sound = new Sound();
	menu =new Menu();
	effect = new Effect();
	item =new Item(item_gh);
	collision =new Collision();
	w_system=new WindowSystem();
	village = new Village();
	chara_admin = new CharacterAdmin();
	event_act = new Event();

	

	
//=================================================================
//初期化 必要なオブジェクトを取得
//=================================================================
	
		player->Init();	
		sound->Init(player);
		hours24->Init();						
		item->Init(player,w_system,sound);
		chara_admin->Init(player,enemy,sound,collision);
		village->Init(player,chara_admin);
		menu->Init(w_system, item, sound);
		event_act->Init(player, w_system, item, menu, this, collision);

	
}
Control::~Control() {
	
	delete event_act;
	
	delete sound;
	delete collision;
	delete village;
	delete chara_admin;
	delete effect;
	delete item;
	delete menu;
	delete hours24;
	delete w_system;


	for (int i = 0; i<ENEMY_NUM; i++) {
		if (enemy[i] != NULL) {
			delete enemy[i];
		}
	}
	delete player;
	
	
}


アバター
へにっくす
記事: 634
登録日時: 11年前
住所: 東京都

Re: ウィンドウを閉じた後のアクセス違反

#5

投稿記事 by へにっくす » 8年前

それぞれのクラスのソースがないのでとりあえずあてずっぽうでいうならば、
Initで指定してるインスタンスは、解放時には必ず存在しないといけないのでは?
例えばitem->Initで指定しているのはplayer、w_system、soundなのでitemより先にその3つのオブジェクトを解放しちゃまずい気がします。
itemより先にsoundをdeleteしてますよね?

Controlのデストラクタを書いたとき、
インスタンスがどういう順序で作成されたのか、また関連付けられているのかをちゃんと考えていましたか?
written by へにっくす

アバター
もるも
記事: 54
登録日時: 8年前
連絡を取る:

Re: ウィンドウを閉じた後のアクセス違反

#6

投稿記事 by もるも » 8年前

deleteの順番を並び替えてみましたが、なおらず・・・。
Itemクラスを症状が起こらないように削ってみたところ、
構造体の初期化の仕方が間違っていました。

コード:

memset(dItem,0,sizeof(dItem)*DROP_ITEM_MAX);		//dItem初期化
配列一個分のサイズと勘違いしていました(汗)

コード:

memset(dItem,0,sizeof(dItem));		//dItem初期化
だいぶ前に書いて放置していたものなので全く気付きませんでした・・・。
まさか後になって不具合が出るとは(><)

へにっくすさん、ありがとうございました。

閉鎖

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