バグ

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
ちゅん

バグ

#1

投稿記事 by ちゅん » 16年前

こんばんは。昨日の今日で誠に申し訳ないのですが、また教えて頂きたいことができました。
今まで正常に動作していたプログラムに突然バグが起こり、困っております。
使用しているのはVisual C++ 2008 EEです。
少し長くなりますが、ご容赦ください。

まず、バグが起こる直前に行った操作です。

GameBaseというクラスにメンバとしてbool hoge[200]を追加。
GameBaseのコンストラクタを用いて
int i;
	for( i = 0; i < 200; i++ ) hoge = false;

 
と初期化。
以上です。この際、初期化部分をコメントアウトすると、エラーがなくなります。

次に、エラーが起こった場所です。
void Chara::setName( char *pName )
{
	size_t size;

	if( pName == NULL )
		return;

	if( m_pName )
	{
		delete m_pName;
		m_pName = NULL;
	}

	size = strlen( pName )+1;
>	m_pName = new char[ size ];  
	
	if( m_pName == NULL )
		return;

	strcpy_s( m_pName, size, pName );
}

 
どうやら、メモリ確保に失敗するようで、std::bad_allocが返ってきています。
setName関数をコメントアウトして飛ばしてみると、次のnewで同じエラーが出ました。
空きメモリは約620MBありますが、これでは足りないのでしょうか。

そして、これがエラーを起こした場所の出力です。
***.exe の 0x7c95ab8e で初回の例外が発生しました: 0xC0000005: 場所 0x00000000 を読み込み中にアクセス違反が発生しました。
***.exe の 0x7c812a6b で初回の例外が発生しました: Microsoft C++ の例外: std::bad_alloc (メモリの場所 0x0012fb08)。
***.exe の 0x7c812a6b でハンドルされていない例外が発生しました: Microsoft C++ の例外: std::bad_alloc (メモリの場所 0x0012fb08)。


最後に、呼び出し履歴です。
kernel32.dll!7c812a6b() 	
 	[下のフレームは間違っているか、または見つかりません。kernel32.dll に対して読み込まれたシンボルはありません。]	
 	kernel32.dll!7c812a6b() 
 	***.exe!_CxxThrowException(void * pExceptionObject=0x0012fb08, const _s__ThrowInfo * pThrowInfo=0x0082a9e8)  行 161	C++
 	***.exe!operator new(unsigned int size=7)  行 64	C++
 	***.exe!operator new[/url](unsigned int count=7)  行 7 + 0x9 バイト	C++
>	***.exe!Chara::setName(char * pName=0x0080139c)  行 50 + 0x9 バイト	C++
 	***.exe!GameBase::init()  行 57	C++
 	***.exe!Game::run()  行 17	C++
 	***.exe!WinMain(HINSTANCE__ * hInstance=0x00400000, HINSTANCE__ * hPrevInstance=0x00000000, char * lpCmdLine=0x00151f46, int nCmdShow=1)  行 28 + 0x8 バイト	C++
 	***.exe!__tmainCRTStartup()  行 263 + 0x2c バイト	C
 	***.exe!WinMainCRTStartup()  行 182	C
 	kernel32.dll!7c816fe7()

 
新しく加えた場所に問題があるように思えません。
原因として考えられる箇所を教えて頂けると幸いです。
どうか宜しくお願い致します。

Justy

Re:バグ

#2

投稿記事 by Justy » 16年前


>原因として考えられる箇所

 new[/url]しようとしたサイズも小さいようですし、挙げられたコードの中には原因になりそうなところは
見あたりません。

 つまり、setName()が呼ばれる以前の処理に問題がある可能性が高いです。

ちゅん

Re:バグ

#3

投稿記事 by ちゅん » 16年前

以前の処理はこのようになっております。
int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow )
{
    if( ChangeWindowMode( TRUE ) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1;

	int result;

	SetTransColor( 68, 14, 98 );
	dat_load();
	SetDrawScreen( DX_SCREEN_BACK );

	Game *pGame = new Game;

	result = pGame->run();

	delete pGame;
 
	DxLib_End();
	return result;
}

int Game::run()
{
	init();
	while( ProcessMessage() == 0 && ClearDrawScreen() == 0 && GetHitKeyStateAll_2(KeyBuf) == 0 && KeyBuf[KEY_INPUT_ESCAPE] == 0)
	{	
		switch(function_status)
		{
			case 0:		
				title();
				break;
			case 1:
				cycle();
				break;
			default:
				DxLib_End();
				return 0;
				break;
		}	
		ScreenFlip();
		if( esc == 1 ) break ;
	}
	return 0;
}
 
setName関数はinit関数の最初の項目です。
GameクラスはGameBaseクラスの子クラスでして、initがループの外に出ているのはコンストラクタを知らなかった頃の名残です。

もしかしてexternで配列を取ると余計にメモリを食ったりしますか?
dat_load用にint型配列をいくつかexternでとってます。たいした量じゃないですが。

Justy

Re:バグ

#4

投稿記事 by Justy » 16年前

 やはりこのコードの中にも原因になりそうな箇所は見あたりません。
 疑わしいのは dat_load()と Gameと GameBaseのコンストラクタ、Game::init()の中です。
 
 試しに dat_loadをコメントアウトしたらどうなりますか?
 これで init()の処理を終えることができたのなら dat_load()が、
だめなら Gameと GameBaseのコンストラクタ、Game::init()あたりを疑ってみてください。

 

>externで配列を取ると余計にメモリを食ったりしますか?

 勿論その分だけ消費しますが、本当にいくつか程度であればほぼ影響はないかと思います。

ちゅん

Re:バグ

#5

投稿記事 by ちゅん » 16年前

dat_loadをコメントアウトしてみたら、Initのみならず他のエラーも吐かず正常に終了できました。
しかし、ある意味困った問題が…
コメントアウトを解いてみたところ、何故か正常に稼動するように。
このまま放っておいたらまずいですよね?

取り敢えず書いておきますけど、Gameのコンストラクタは空、GameBaseは変数メンバを初期化しているだけです。
initの中身も
void GameBase::init()
{
	m_player.setName("hoge");
	m_player.m_status.setParameter( NULL ); //ステータス初期化

	messageMake(); //メッセージウィンドウ作成
}
 
と特に何もないと思われます。
お騒がせしてしまい本当にすいません。

お騒がせついでに1つお尋ねしたいのですが、エラーが出たときの原因は決まってそれ以前にあるものなんですか?
実は今回、よく解らないエラーなこともあって何処を探せばよいかわからず、かなりの時間を使ってしまいましたので…
またバグが発生したときの参考にさせて頂きます。

Justy

Re:バグ

#6

投稿記事 by Justy » 16年前


>このまま放っておいたらまずいですよね?

 再発する可能性があるので、再度再現可能なら原因は調べた方がいいですね。
 でも、単純にビルドした各オブジェクトの整合性がうまくとれていなかっただけかもしれません。
(その場合はもう調べようがないかも……)



>エラーが出たときの原因は決まってそれ以前にあるものなんですか?

 普通はそうですね。

ちゅん

Re:バグ

#7

投稿記事 by ちゅん » 16年前

バグの起爆剤となった部分(bool hoge[200])をコメントアウトしたり戻したりしても何も起こりませんし、
今日もプログラムを少し弄っていましたが、特に何も起こりません。
手の出しようがないので、もしまた起こった際に対策を考えてみます。

Justyさん、いろいろとご指導頂き本当にありがとうございました!

閉鎖

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