exeファイルの動作が安定しない

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

exeファイルの動作が安定しない

#1

投稿記事 by 染み » 12年前

敵を生成する処理(newでメモリを確保して双方向リストで繋げる)が、VisualC++のデバッグでは正常に動作するのですが、
releaseで生成したexeファイルでは場合によって成功したり失敗したりします。
原因としては敵クラス(IndividualEnemyクラス)のメンバが多すぎてクラスのサイズが大きくなり、メモリ確保に失敗していることが考えられるのですが、色々試してもうまくいきません。
初心者ゆえ読みにくいコードですが、解決方法をご教授お願いします。

IndividualEnemyクラス

コード:

class GameObj
{
public:
	float x, y, z; //基準点
	short int Range1x, Range1y, Range2x, Range2y;
	bool Display;
};

class IndividualEnemy : public GameObj
{
public:
	short int Range1x, Range1y, Range2x, Range2y; // 範囲の座標
	short int Direction; // 向き << 上:0 下:1 右:2 左:3 >>
	float rad; // 向きの角度
	short int DrawImageNumber; // 描画する画像の番号
	short int HP; // 残り体力
	short int Damage; //攻撃力
	short int Moving; // 移動しているかどうか << 移動中:1以上 停止中:0 >>
	short int InvincibleTime; // 無敵時間
	bool Invincible; // 攻撃を受けるかどうか << 受けない:true 受ける:false >>
	short int AttackDelay; // 攻撃タイミングのズレ
	short int TimingCount; // 各種タイミング計り変数
	bool HitAttack; // 接触でプレイヤーがダメージを受けるかどうか << true:受ける false:受けない >>
	bool Display; // 表示するかどうか
	bool Armor; // 被ダメージ時に仰け反るかどうか << 仰け反る:true 仰け反らない:false>>
	IndividualEnemy *prev;
	IndividualEnemy *next;
};
敵生成関数(メモリ確保)

コード:

void Enemy_Create(int EnemyType, int x, int y, int Direction, int AttackDelay){
	IndividualEnemy *n, *e = &ET[EnemyType].head;
	
	for(IndividualEnemy *p = ET[EnemyType].head.next; p != NULL; p = p->next){ //最後尾のアドレスを検索
		e = p;
	}

	n = new IndividualEnemy;

	n->x = x;
	n->y = y;
	n->Direction = Direction;
	n->AttackDelay = AttackDelay;
	n->Display = true;
	n->HP = ET[EnemyType].HP; // 体力の設定
	n->HitAttack = ET[EnemyType].HitAttack; // 接触ダメージの設定
	n->InvincibleTime = 0; // 無敵時間の設定
	n->Invincible = ET[EnemyType].Invincible; // 無敵の種族を無敵化
	n->Moving = 0; // 移動時間の初期化
	n->DrawImageNumber = n->Direction; // 描画画像の初期化
	n->TimingCount = 0; // タイミングの初期化
	n->Damage = ET[EnemyType].Damage;

	n->next = NULL;
	n->prev = e;
	e->next = n;

	ET[EnemyType].Population++;
}


アバター
h2so5
副管理人
記事: 2212
登録日時: 14年前
住所: 東京
連絡を取る:

Re: exeファイルの動作が安定しない

#2

投稿記事 by h2so5 » 12年前

染み さんが書きました:敵を生成する処理(newでメモリを確保して双方向リストで繋げる)が、VisualC++のデバッグでは正常に動作するのですが、
releaseで生成したexeファイルでは場合によって成功したり失敗したりします。
原因としては敵クラス(IndividualEnemyクラス)のメンバが多すぎてクラスのサイズが大きくなり、メモリ確保に失敗していることが考えられるのですが、色々試してもうまくいきません。
具体的にどういった症状がでるのかがよく分かりません。
newでメモリ確保に失敗した場合はstd::bad_allocが投げられますが、その確認はされましたか?

アバター
馬場自由
記事: 15
登録日時: 12年前

Re: exeファイルの動作が安定しない

#3

投稿記事 by 馬場自由 » 12年前

ちょっとメンバが多い程度でメモリ確保に失敗するとは思えません。
newした時にNULLが返ってきたのなら、確かにメモリが足りないのかもしれませんが、試しましたか?

それと、配列ETは何が入ったものですか。

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: exeファイルの動作が安定しない

#4

投稿記事 by softya(ソフト屋) » 12年前

単に双方向リストの管理に失敗しているだけかもしれません。
あるいは別のバグかもしれませんので、詳細な情報をお願いします。
たった、これだけのメンバでクラスのnewが出来なくなるとは思えません。
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: exeファイルの動作が安定しない

#5

投稿記事 by ISLe » 12年前

リリースビルドで問題が出るパターンには、変数の初期化の違いがあります。

ET[EnemyType].headのリンクポインタが初期化されてなくて不正なアクセスしてるとか。

染み

Re: exeファイルの動作が安定しない

#6

投稿記事 by 染み » 12年前

返信ありがとうございます。言葉足らずで申し訳ありません。
具体的には、敵を沢山生成するボス敵がいるのですが、生成するときに同時に5個生成されるはずが、全く生成されなかったり、1個しか生成されなかったり、ちゃんと5個生成されたりと生成処理の成功率がまちまちなのです。
普段はVisualC++のreleaseモードでデバッグしているのですが、この時はちゃんと動作します。

newでNULLが返ってきているかどうかですが、

コード:

n = new IndividualEnemy;
if(n == NULL) DxLib_End();
で確認したところ返ってきてないようです。
スローについてはあまりC++は勉強していないのでよく分かりませんでした。すみません。

配列ETはEnemyType構造体の変数で、種類別の敵の設定が入っています。

コード:

// エネミー構造体
typedef struct EnemyType{
	short int Population; // 個体数
	short int Size_x, Size_y; // 判定の大きさ
	short int UpSpace, DownSpace, RightSpace, LeftSpace; // 上下左右のスペース
	short int HP; // 体力
	short int Damage; // プレイヤーに与えるダメージ
	short int MoveType; // 移動AI
	short int AttackType; // 攻撃方法
	bool Invincible; // 無敵かどうか << 無敵:true 無敵でない:false >>
	short int AgainstBlock; // 壁をすり抜けるかどうか << 0:ぶつかる 1:すり抜ける 2:破壊する >>
	bool BlockType; // ブロック判定かどうか << true:ブロック false:通過 >>
	bool Floating; // 穴を超えられるかどうか << true:超えられる false:超えられない >>
	bool HitAttack; // 接触でプレイヤーがダメージを受けるかどうか << true:受ける false:受けない >>
	bool Armor; // 被ダメージ時に仰け反るかどうか << 仰け反る:true 仰け反らない:false>>
	bool Boss; // ボスかどうか << ボス:true ザコ:false>>
	int DrawPriority; // 描画優先度 << -1:先 0:普通 1:後 >>
	IndividualEnemy head; // リストの先頭
}EnemyType; // 種類別
また、最初に敵を生成する(マップファイルから敵の種類や位置を読み込む)時にはEnemy_Create()関数は使わずに以下のようにしています

コード:

IndividualEnemy *p[EnemyTypeNumber], *n;
for(int i = 0; i < EnemyTypeNumber; i++){
	p[i] = &ET[i].head;
	ET[i].head.prev = NULL; ET[i].head.next = NULL;
	ET[i].Population = 0; //総数初期化
}

// 読み込んだデータでリストを作成
for(int i = 0; i < MapSize_x; i++){
	for(int j = 0; j < MapSize_y; j++){
		if(EnemyData[i][j] != 0){
			n = new IndividualEnemy;

			n->x = MapPlace_x + (i *GridSize); //位置設定
			n->y = MapPlace_y + (j *GridSize);
			n->z = 0;
			
			n->Direction = EnemyDirection[i][j]; // 初期方向
			n->AttackDelay = EnemyAttackDelay[i][j]; // 攻撃ディレイ

			n->HP = ET[EnemyData[i][j]].HP; // 体力の設定
			n->HitAttack = ET[EnemyData[i][j]].HitAttack; // 接触ダメージの設定
			n->InvincibleTime = 0; // 無敵時間の設定
			n->Invincible = ET[EnemyData[i][j]].Invincible; // 無敵の種族を無敵化
			n->Moving = 0; // 移動時間の初期化
			n->DrawImageNumber = n->Direction; // 描画画像の初期化
			n->TimingCount = 0; // タイミングの初期化
			n->Damage = ET[EnemyData[i][j]].Damage; //攻撃力の設定
			n->Display = true;
			n->Armor = ET[EnemyData[i][j]].Armor;
			n->next = NULL;
			n->prev = p[EnemyData[i][j]];
			p[EnemyData[i][j]]->next = n;
			p[EnemyData[i][j]] = n;
			ET[EnemyData[i][j]].Population++;
		}
	}
}

アバター
softya(ソフト屋)
副管理人
記事: 11677
登録日時: 14年前
住所: 東海地方
連絡を取る:

Re: exeファイルの動作が安定しない

#7

投稿記事 by softya(ソフト屋) » 12年前

同じReleaseでもデバッガから動かす時と直接実行すると時は動作が変わる場合があります。
あとReleaseではデバッガでちゃんと命令実行やデータの監視は最適化されるため行えませんので、提案としてOutputDebugString()で生成状況や生成の元になるデータを通知するようにして監視できるようにしてみてはどうでしょう。

exeから直接起動して下記のソフトなどを使いOutputDebugString()の情報をリアルタイムで監視できます。
「DbgMOnの詳細情報 : Vector ソフトを探す!」
http://www.vector.co.jp/soft/win95/prog/se169346.html
by softya(ソフト屋) 方針:私は仕組み・考え方を理解して欲しいので直接的なコードを回答することはまれですので、すぐコードがほしい方はその旨をご明記下さい。私以外の方と交代したいと思います(代わりの方がいる保証は出来かねます)。

dic
記事: 658
登録日時: 14年前
住所: 宮崎県
連絡を取る:

Re: exeファイルの動作が安定しない

#8

投稿記事 by dic » 12年前

無視のようなので消します

染み
記事: 1
登録日時: 12年前
住所: 茨城県
連絡を取る:

Re: exeファイルの動作が安定しない

#9

投稿記事 by 染み » 12年前

返信が遅れて申し訳ありません。
softyaさんが提案して下さった方法でバグの原因を発見することが出来ました。
どうやら敵を生成する時に判定が初期化されておらず、敵を消す判定にすぐに引っかかっていたのが原因のようです。

言葉足らずな質問に真摯に回答して下さって、皆さんありがとうございました。
これからはこまめにexeファイルでも試すようにしたいと思います。

ISLe
記事: 2650
登録日時: 14年前
連絡を取る:

Re: exeファイルの動作が安定しない

#10

投稿記事 by ISLe » 12年前

フォーラムルールを守らない回答者も目立ってきましたね。

dic
記事: 658
登録日時: 14年前
住所: 宮崎県
連絡を取る:

Re: exeファイルの動作が安定しない

#11

投稿記事 by dic » 12年前

>>染みさん
気分を害するような発言をして、すいませんでした。


日常で、原因はわかりませんが、その日の私は気分を害していたと思います。
それゆえ、染みさんの発言には問題がないのですが、変な返答をしてしまいました。
重ねてすいませんでした。

閉鎖

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