メモリ使用量がどんどん増えます

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

メモリ使用量がどんどん増えます

#1

投稿記事 by gentoo » 8年前

DXライブラリで縦スクロールシューティングを作っています。
その中で、ステージを順番にクリアするモードがあるのですが、
switch(flag){
case 0:
pS = new Stage();
pS->Init(stage_num);
flag = ;
break;
case 1:
pS->Display();
if(pS->GetState()){
flag = 2;
}
break;
case 2:
delete pS;
stage_num++;
flag = 0;
break;
}
(かなり要約しています)
このループをまわるたびにメモリ使用量が増えて、途中で止まってしまいます。組み方に問題があるのか、教えていただけると助かります。

だんごさん
記事: 273
登録日時: 12年前

Re: メモリ使用量がどんどん増えます

#2

投稿記事 by だんごさん » 8年前

コード:

switch(flag){
	case 0:
		pS = new Stage();
		pS->Init(stage_num);
		flag = ;
	break;
	case 1:
		pS->Display();
		if(pS->GetState()){
		flag = 2;
		}
	break;
	case 2:
		delete pS;
		stage_num++;
		flag = 0;
	break;
}
ソースコードはcodeタグで囲みましょう。
5行目flagの値が代入されていませんがflag = 1;ということでしょうか?
またstage_numの上限を設定してないように思えますが大丈夫でしょうか?
 Dango San

gentoo

Re: メモリ使用量がどんどん増えます

#3

投稿記事 by gentoo » 8年前

返信遅くなり申し訳ありません。codeタグは送信した後に気づきました。

5行目flag = 1;であっています。脱字ですね。
stage_numは、6未満のときインクリメントでした。

メインの関数

コード:

#include "main.h"
#include "Title.h"
#include "Stage.h"
#include "MainMenu.h"
#include "SaveData.h"
#include "SoundEffect.h"
#include "Hangar.h"
#include "MissionSelect.h"
#include "Opening.h"
#include "Ending.h"
#include "Loading.h"
#include "Retry.h"
#include "Clear.h"

int WINAPI WinMain(HINSTANCE,HINSTANCE,LPSTR,int){
	ChangeWindowMode( TRUE ) ;

    if( DxLib_Init() == -1 ) {
         return -1;
    }
	int gamestate_out = 0;//0でタイトル、1でメニュー、2でストーリー、3でセレクト、4でハンガー、5で終了
	int gamestate_in = 0;//内部状態
	int select_plane = 1;
	int select_stage = 1;
	int key_flag = 1;
	int succesive = 0;
	int color_box = GetColor(0,0,127);
	
	Stage* pStage;
	Loading* pLoad;
	Clear* pClear;
	Retry* pRetry;

	pStage = NULL;
	pLoad = NULL;
	pClear = NULL;
	pRetry = NULL;

	Title title;
	MainMenu mainmenu;
	SaveData savedata;
	Hangar hangar;
	MissionSelect select;
	SoundEffect se;
	Opening open;
	Ending end;

	se.set();
	savedata.Load();
	
	//メインループ
	while(TRUE){
		ClearDrawScreen();
		
		if(gamestate_out == 0){
			//タイトル。Enterキーでgamestate_out = 1;
		}
		if(gamestate_out == 1){
			//メインメニュー。ここでgamestate_outが2から5に分岐
		}
		if(gamestate_out == 2){
			//キャンペーン
			switch(gamestate_in){
			case 0:
				open.set(savedata.data.player);
				savedata.data.story = 1;
				gamestate_in = 1;
			case 1:
				if(open.GetState()){
					open.Display();
				}else{
					gamestate_in = 2;
					pLoad = new Loading();
					printfDx("①");
					pLoad->Set(savedata.data.story);
					pLoad->Display();
				}
				break;
			case 2:
				delete pLoad;
				printfDx("②");
				pStage = new Stage();
				printfDx("①");
				pStage->Set(savedata.data.story,savedata.data.player);//このへん!
				gamestate_in = 3;
				succesive = 0;
				break;
			case 3:
				if(pStage->GetState()){
					pStage->Display();
				}else{
					if(pStage->GetSuccesive()){
						pClear = new Clear();
						printfDx("①");
						pClear->set(pStage->GetScore());
						savedata.data.credit += pStage->GetScore();
						pStage->bgm.Stop();
						delete pStage;
						printfDx("②");
						gamestate_in = 4;
						succesive = 1;
					}else{
						pRetry = new Retry();
						printfDx("①");
						pRetry->set();
						pStage->bgm.Stop();
						gamestate_in = 4;
					}
					
				}
				break;
			case 4:
				if(succesive){
					pClear->Display();
					if(key_flag){
						if(CheckHitKey(KEY_INPUT_RETURN)){
							if(savedata.data.story < 6){
								savedata.data.story++;
								gamestate_in = 2;
								delete pClear;
								printfDx("②");
								pLoad = new Loading();
								printfDx("①");
								pLoad->Set(savedata.data.story);
								pLoad->Display();
							}else{
								end.set(savedata.data.player);
								delete pClear;
								printfDx("②");
								gamestate_in = 5;
							}
							key_flag = 0;
						}
					}else if(CheckHitKeyAll()==0){
						key_flag = 1;
					}
				}else{
					pRetry->Display();
					if(key_flag){
						if(CheckHitKey(KEY_INPUT_RETURN)){
							gamestate_in = 3;
							pStage->Init();
							delete pRetry;
							printfDx("②");
							key_flag = 0;
						}
					}else if(CheckHitKeyAll()==0){
						key_flag = 1;
					}
				}
				break;
			case 5:
				if(end.GetState()){
					end.Display();
				}else{
					gamestate_out = 1;
					gamestate_in = 0;
				}
				break;
			}
		}
		if(gamestate_out == 3){
			//ミッション選択モード	
		}
		if(gamestate_out == 4){
			//機体購入、乗り換え
		}
		if(gamestate_out == 5){
			//終了処理
			savedata.Save();
			if(gamestate_in){//未完成
				break;
			}
		}

		ScreenFlip();

		if( ProcessMessage() == -1 ){
                break ;
            }
	}

    DxLib_End();
    return 0;
}
Stageクラス

コード:

#include"main.h"
#include"Stage.h"
void Stage::Set(int stage,int plane){
	state.stage_select = stage;

	count_air = 0;
	wait_air = 0;
	count_ground = 0;
	wait_ground = 0;
	flag_air = 0;
	flag_ground = 0;
	succesive = 0;

	bgm.set();

	switch(state.stage_select){
	case 1:
		background_graph = LoadGraph("graph/map/stage1.png");
		for(int i=0;i<ENEMY_NUM;i++){
			enai[i].set("graph/plane/enm1.png",32,48,100);
		}
		for(int i=0;i<2;i++){
			tgtai[i].set("graph/plane/enm2.png",96,96,200);
		}
		bgm.Play(1);
		break;
	case 2:
		background_graph = LoadGraph("graph/map/stage2.png");
		for(int i=0;i<ENEMY_NUM;i++){
			engl[i].set("graph/enemy/enm3.png",16,16,100);
			engl[i].Init(0,0);
		}
		for(int i=0;i<2;i++){
			tgtgl[i].set("graph/enemy/fob.png",48,48,200);
		}
		bgm.Play(2);
		break;
	case 3:
		background_graph = LoadGraph("graph/map/stage3.png");
		for(int i=0;i<ENEMY_NUM;i++){
			engl[i].set("graph/enemy/enm1.png",32,48,100);
			engl[i].Init(0,0);
		}
		for(int i=0;i<2;i++){
			tgtgl[i].set("graph/enemy/enm2.png",96,96,400);
		}
		bgm.Play(2);
		break;
	case 4:
		background_graph = LoadGraph("graph/map/stage4.png");
		for(int i=0;i<ENEMY_NUM;i++){
			enai[i].set("graph/plane/enm1.png",32,48,100);
		}
		for(int i=0;i<2;i++){
			tgtai[i].set("graph/plane/enm2.png",96,96,400);
		}
		bgm.Play(3);
		break;
	case 5:
		background_graph = LoadGraph("graph/map/stage5.png");
		for(int i=0;i<ENEMY_NUM;i++){
			enai[i].set("graph/plane/enm1.png",32,48,100);
		}
		for(int i=0;i<2;i++){
			tgtai[i].set("graph/plane/enm_last.png",192,96,600);
		}
		bgm.Play(4);
		break;
	}

	background_pos = -3840;

	player.set("graph/plane/f-4.png",32,48,PLR_DEF);
	wingman.set("graph/plane/fa-18w.png",32,48,WIM_DEF);
	player.Init();
	wingman.Init();

	score.Set();

	state.stage_state = 0;
}
void Stage::Init(){
	count_air = 0;
	wait_air = 0;
	count_ground = 0;
	wait_ground = 0;
	flag_air = 0;
	flag_ground = 0;
	succesive = 0;

	background_pos = -3840;

	player.defence = PLR_DEF;

	player.Init();
	wingman.Init();

	score.Set();

	bgm.Start();

	state.stage_state = 0;
}
void Stage::Display(){
	//背景描画
	DrawGraph(0,background_pos,background_graph,FALSE);
	//ボス戦に移行
	if(state.stage_state == 0){
		if(background_pos >= -480){
			state.stage_state = 1;
		}
	}
	if(state.stage_state == 2){
		if(background_pos >= 0){
			state.stage_state = 3;
			bgm.Stop();
		}
	}

	if(state.stage_select==2 || state.stage_select==3){
		//対地湧き
		if(state.stage_state == 0){
			//雑魚敵
			if(wait_ground % ENGL_WAIT == 0){
				flag_ground = GetRand(19);
				if(engl[flag_ground].disp_flg != 1){
					engl[flag_ground].Spawn(flag_ground*32+16);
				}
			}
			wait_ground++;
			for(int i=0;i<ENEMY_NUM;i++){
				engl[i].Display();
				if(engl[i].disp_flg){
					engl[i].AutoAttack(player.GetX());
				}
			}
			wingman.AutoPilot(engl[flag_ground].pos_x);
			//ボス
		}else if(state.stage_state == 1){
			tgtgl[0].Spawn(160);
			tgtgl[1].Spawn(480);
			state.stage_state = 2;
		}else if(state.stage_state == 2){
			tgtgl[0].Display();
			tgtgl[1].Display();
			//ボス当たり判定
			for(int i=0;i<2;i++){
				for(int j=0;j<SHOT_NUM;j++)
					if(
						(tgtgl[i].GetY()-player.shot.GetY(j))*(tgtgl[i].GetY()-player.shot.GetY(j)) +
						(tgtgl[i].GetX()-player.shot.GetX(j))*(tgtgl[i].GetX()-player.shot.GetX(j)) <
						(COL_SIZE_TGT*COL_SIZE_TGT)
					){
						if(player.shot.fly_flag[j]){
							score.ScoreInc(tgtgl[i].DecreaseDefence(SHOT_DMG));
							player.shot.fly_flag[j] = 0;
						}

					}
			}
		}

		//当たり判定
		for(int i=0;i<ENEMY_NUM;i++){
			for(int j=0;j<SHOT_NUM;j++){
				//自機の当たり判定
				if(
					(player.GetY()-engl[i].shot.GetY(j))*(player.GetY()-engl[i].shot.GetY(j)) + 
					(player.GetX()-engl[i].shot.GetX(j))*(player.GetX()-engl[i].shot.GetX(j)) <
					(COL_SIZE_STD*COL_SIZE_STD)
				){
					if(engl[i].shot.fly_flag[j]){
						player.DecreaseDefence(SHOT_DMG);
						engl[i].shot.fly_flag[j] = 0;
						if(player.defence <= 0){
							state.stage_state = 3;
						}
					}
				}
				//僚機の当たり判定
				if(
					(engl[i].GetY()-wingman.shot.GetY(j))*(engl[i].GetY()-wingman.shot.GetY(j)) +
					(engl[i].GetX()-wingman.shot.GetX(j))*(engl[i].GetX()-wingman.shot.GetX(j)) <
					(COL_SIZE_STD*COL_SIZE_STD)
				){
					if(engl[i].disp_flg){
						score.ScoreInc(engl[i].DecreaseDefence(SHOT_DMG));
						wingman.shot.fly_flag[j] = 0;
					}
				}
				//敵機の当たり判定
				if(
					(engl[i].GetY()-player.shot.GetY(j))*(engl[i].GetY()-player.shot.GetY(j)) +
					(engl[i].GetX()-player.shot.GetX(j))*(engl[i].GetX()-player.shot.GetX(j)) <
					(COL_SIZE_STD*COL_SIZE_STD)
				){
					if(engl[i].disp_flg){
						score.ScoreInc(engl[i].DecreaseDefence(SHOT_DMG));
						player.shot.fly_flag[j] = 0;
					}
				}
			}
		}
		
		//成功判定
		if(tgtgl[0].disp_flg == 2 && tgtgl[1].disp_flg == 2){
			succesive = 1;
		}
	}
	if(state.stage_select==1 || state.stage_select==4 || state.stage_select==5){
		//対空湧き
		if(state.stage_state == 0){
			//雑魚敵
			if(wait_air % ENAI_WAIT == 0){
				flag_air = GetRand(19);
				if(enai[flag_air].disp_flg != 1){
					enai[flag_air].Spawn(flag_air*32+16);
				}
			}
			wait_air++;
			for(int i=0;i<ENEMY_NUM;i++){
				enai[i].Display();
				if(enai[i].disp_flg){
					enai[i].Attack(player.GetX());
				}
			}
			wingman.AutoPilot(enai[flag_air].pos_x);
			//ボス
		}else if(state.stage_state == 1){
			if(state.stage_select == 5){
				tgtai[0].Spawn(320);
				tgtai[1].Spawn(320);
			}else{
				tgtai[0].Spawn(160);
				tgtai[1].Spawn(480);
			}
			state.stage_state = 2;
		}else if(state.stage_state == 2){
			tgtai[0].Display();
			tgtai[1].Display();
			//ボス当たり判定+回避
			for(int i=0;i<2;i++){
				for(int j=0;j<SHOT_NUM;j++){
					if(player.shot.fly_flag[j]){
						if(state.stage_select < 5){
							tgtai[i].Evade(player.shot.GetX(j));
						}
					}
					if(
						(tgtai[i].GetY()-player.shot.GetY(j))*(tgtai[i].GetY()-player.shot.GetY(j)) +
						(tgtai[i].GetX()-player.shot.GetX(j))*(tgtai[i].GetX()-player.shot.GetX(j)) <
						(COL_SIZE_TGT*COL_SIZE_TGT)
					){
						if(player.shot.fly_flag[j]){
							score.ScoreInc(tgtai[i].DecreaseDefence(SHOT_DMG));
							player.shot.fly_flag[j] = 0;
						}

					}
				}
			}
		}

		for(int i=0;i<ENEMY_NUM;i++){
			for(int j=0;j<SHOT_NUM;j++){
				//自機の当たり判定
				if(
					(player.GetY()-enai[i].shot.GetY(j))*(player.GetY()-enai[i].shot.GetY(j)) + 
					(player.GetX()-enai[i].shot.GetX(j))*(player.GetX()-enai[i].shot.GetX(j)) <
					(COL_SIZE_STD*COL_SIZE_STD)
				){
					if(enai[i].shot.fly_flag[j]){
						player.DecreaseDefence(SHOT_DMG);
						enai[i].shot.fly_flag[j] = 0;
						if(player.defence <= 0){
							state.stage_state = 3;
						}
					}
				}
				//僚機の当たり判定
				if(
					(enai[i].GetY()-wingman.shot.GetY(j))*(enai[i].GetY()-wingman.shot.GetY(j)) +
					(enai[i].GetX()-wingman.shot.GetX(j))*(enai[i].GetX()-wingman.shot.GetX(j)) <
					(COL_SIZE_STD*COL_SIZE_STD)
				){
					if(enai[i].disp_flg){
						score.ScoreInc(enai[i].DecreaseDefence(SHOT_DMG));
						wingman.shot.fly_flag[j] = 0;
					}
				}
				//敵機の当たり判定
				if(
					(enai[i].GetY()-player.shot.GetY(j))*(enai[i].GetY()-player.shot.GetY(j)) +
					(enai[i].GetX()-player.shot.GetX(j))*(enai[i].GetX()-player.shot.GetX(j)) <
					(COL_SIZE_STD*COL_SIZE_STD)
				){
					if(enai[i].disp_flg){
						score.ScoreInc(enai[i].DecreaseDefence(SHOT_DMG));
						player.shot.fly_flag[j] = 0;
					}
				}
			}
		}
		
		//成功判定
		if(tgtai[0].disp_flg == 0 && tgtai[1].disp_flg == 0){
			succesive = 1;
		}
	}

	//友軍描画
	wingman.Display();
	player.Display();

	player.ManualPilot();

	background_pos = background_pos + ENGL_SPD;
}
int Stage::GetState(){
	if(state.stage_state <3){
		return TRUE;
	}else{
		return FALSE;
	}
}
int Stage::GetScore(){
	return score.score;
}
int Stage::GetSuccesive(){
	if(succesive){
		return TRUE;
	}else{
		return FALSE;
	}
}
デストラクタを作るべきでしょうか…

だんごさん
記事: 273
登録日時: 12年前

Re: メモリ使用量がどんどん増えます

#4

投稿記事 by だんごさん » 8年前

おそらくdeleteしてもDxLibで読み込んだ画像はメモリに残っていると思いますので
DeleteGraphを呼んであげるようにすればよいと思います。
 Dango San

gentoo

Re: メモリ使用量がどんどん増えます

#5

投稿記事 by gentoo » 8年前

アドバイスありがとうございます。
試験的にInitGraphとInitSoundMemで全削除してみたところ、正常に動作するようになりました。
あとは、メモリ解放の関数(DeleteGraph/DeleteSoundMemを実行)を追加するだけで済みそうです。

閉鎖

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