タスククラスの例外

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

タスククラスの例外

#1

投稿記事 by Suikaba » 9年前

ここでまた質問させていただきます。

コード:

// Task.cpp

#include "Task.h"
#include <stdio.h>
#include <assert.h>


//=============================================================
// タスクリストの初期化
CTaskList::CTaskList(int max_task_size, int max_num_task)
:	MaxTaskSize(max_task_size), MaxNumTask(max_num_task), 
	NumFreeTask(max_num_task)
{
	// タスク初期化用のマクロ
	#define TASK(INDEX) ((CTask*)(buf+max_task_size*(INDEX)))

	// タスク用メモリの確保
	char* buf=new char[max_task_size*(max_num_task+2)];

	// アクティブタスクリストの初期化
	ActiveTask=TASK(0);
	ActiveTask->Prev=ActiveTask->Next=ActiveTask;

	// フリータスクリストの初期化
	FreeTask=TASK(1);
	for (int i=1; i<max_num_task+1; i++) {
		TASK(i)->Next=TASK(i+1);
	}
	TASK(max_num_task+1)->Next=FreeTask;
}


//=============================================================
// タスクの生成
// フリータスクリスト上では、メモリブロックの先頭にCTaskを配置する。
// サブクラスのコンストラクタを呼び出した後には、
// メモリブロックの先頭にCTaskが配置されるとは限らない(多重継承など)
// そこで、生成処理をnewとコンストラクタに分割する。
// 削除処理も同様にデストラクタとdeleteに分割する。

// newの処理
void* CTask::operator_new(size_t t, CTaskList* task_list) {

	// クラスサイズが最大サイズを超えたらエラー
	assert(t<=(size_t)task_list->MaxTaskSize);

	// フリータスクがないときはNULLを返す
	if (task_list->NumFreeTask<=0) return NULL;

	// フリータスクを1個取り出す
	CTask* task=task_list->FreeTask->Next;
	task_list->FreeTask->Next=task->Next;
	task_list->NumFreeTask--;
	
	// コンストラクタへ
	return task;
}

// コンストラクタ
CTask::CTask(CTaskList* task_list)
:	TaskList(task_list)
{

	// タスクをアクティブタスクリストに挿入する
	Prev=task_list->ActiveTask->Prev;
	Next=task_list->ActiveTask;
	Prev->Next=Next->Prev=this;
}


//=============================================================
// タスクの削除

// デストラクタ
CTask::~CTask() {

	// タスクをアクティブタスクリストから削除する
	Prev->Next=Next;
	Next->Prev=Prev;
}

// deleteの処理
void CTask::operator_delete(void* p, CTaskList* task_list) {

	// タスク
	CTask* task=(CTask*)p;

	// タスクをフリータスクリストに挿入する
	task->Next=task_list->FreeTask->Next;
	task_list->FreeTask->Next=task;
	task_list->NumFreeTask++;

	// フリータスク数が最大タスク数を超えたらエラー
	// (deleteの重複呼び出しなど)
	assert(task_list->NumFreeTask<=task_list->MaxNumTask);
}


//=============================================================
// 全タスクの消去
void CTaskList::DeleteTask() {
	for (CTaskIter i(this); i.HasNext(); i.Next(), i.Remove()) ;
}

コード:

// Task.h

#ifndef TASKH
#define TASKH

class CTask;
class CTaskList;
class CTaskIter;


//==============================================================
// タスク
class CTask {
friend CTaskList;
friend CTaskIter;

	// タスクリストへのポインタ
	CTaskList* TaskList;

	// 前後のタスクへのポインタ
	CTask *Prev, *Next;

	// タスクリストを指定しないnew, deleteを無効にする
	void* operator new(size_t t) {}
	void operator delete(void* p) {}

protected:
	
	// new, deleteの処理:
	// 適切なnew, delete演算子をサブクラスで定義する
	static void* operator_new(size_t t, CTaskList* task_list);
	static void operator_delete(void* p, CTaskList* task_list);

public:
	CTask(CTaskList* task_list);
	virtual ~CTask();
};


//==============================================================
// タスクリスト
class CTaskList {
friend CTask;
friend CTaskIter;

	// アクティブタスクリスト、フリータスクリスト
	CTask *ActiveTask, *FreeTask;

	// タスクの最大サイズ、タスクの最大数
	int MaxTaskSize, MaxNumTask;
	
	// フリータスクの数
	int NumFreeTask;

public:

	// コンストラクタ
	CTaskList(int max_task_size, int max_num_task);
	
	// タスクの数
	int GetNumFreeTask() { return NumFreeTask; }
	int GetNumActiveTask() { return MaxNumTask-NumFreeTask; }

	// 全タスクの消去
	void DeleteTask();
};


//==============================================================
// タスクイテレータ
class CTaskIter {
protected:
	CTaskList* TaskList;
	CTask* Task;
public:

	// コンストラクタ
	inline CTaskIter(CTaskList* task_list)
	: TaskList(task_list), Task(task_list->ActiveTask)
	{}

	// 次の要素があるときtrue
	inline bool HasNext() {
		return Task->Next!=TaskList->ActiveTask;
	}

	// 次の要素を返す
	inline CTask* Next() {
		return Task=Task->Next;
	}

	// 直前に返した要素を削除する
	inline void Remove() {
		Task=Task->Prev;
		delete Task->Next;
	}
};


#endif


こんな感じでみようみまねで作ってみたのですが、どうも例外が発生してしまってうまくいきません
ずっと考えているのですが、結局わかりませんでした。
誰か教えていただけるとありがたいです。よろしくお願いします。

開発環境
Windows XP
Visual C++ 2008

Poco
記事: 161
登録日時: 9年前

Re: タスククラスの例外

#2

投稿記事 by Poco » 9年前

状況が再現できるソースコードを提示していただけませんか?

Suikaba
記事: 194
登録日時: 9年前

Re: タスククラスの例外

#3

投稿記事 by Suikaba » 9年前

コード:

CShtGame::CShtGame()
: CGame( _T("テスト") )
{
	ShowCursor( FALSE );

	LPDIRECT3DDEVICE9 device = Graphics->GetDevice();

	MyShip = NewTexture( "Bar.bmp" ); // てすとの画像 つまり自機の画像です
	MyShipList = new CTaskList( sizeof( MyShip ), 10 );
}


INT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPTSTR, int )
{
	Game = new CShtGame();
	new CMyShip( 0, 30 ); 
	Game->Run();
	delete Game;
	return 0;
}


Suikaba
記事: 194
登録日時: 9年前

Re: タスククラスの例外

#4

投稿記事 by Suikaba » 9年前

メインルーチンのCMyShipはTaskListクラスとは違いますので、気にしないでください

Poco
記事: 161
登録日時: 9年前

Re: タスククラスの例外

#5

投稿記事 by Poco » 9年前

提示された再現コードでは、コンパイルを通せません。
とりあえず、提示されたソースコードからCTaskクラスやCTaskListクラスに関係ありそうな部分だけで
テストコードを組みましたが、例外は発生しません。

コード:

#include "Task.h"
int main() {
	CTaskList * list = new CTaskList(10, 10);
}

Suikaba
記事: 194
登録日時: 9年前

Re: タスククラスの例外

#6

投稿記事 by Suikaba » 9年前

そうですか・・・どうしましょう。
もう少し考えてみて、わからなかったらコード載せます。

アバター
lriki
記事: 88
登録日時: 9年前

Re: タスククラスの例外

#7

投稿記事 by lriki » 9年前

多分タスククラスの使い方が間違ってる気がします。
貼っていただいてるソースコードでは実行できないので(多分全部貼るのもキツイだろうし…)もうちょっと詳しく教えてください。
私も前にこのタスククラスを研究してたので心当たりがあるかも。

・例外が起こっている場所(と、できればその種類)
・CShtGame の宣言
・CMyShip の宣言とコンストラクタの定義

Suikaba
記事: 194
登録日時: 9年前

Re: タスククラスの例外

#8

投稿記事 by Suikaba » 9年前

例外が起こる場所
CTaskのコンストラクタ 67行目

CShtGameは大丈夫です。しかもこれは載せられない・・・・

CMyShip

コード:

//MyShip.h

#pragma once 

#include "Mover.h"


//==================================================================
// This class is my ship
// 自機のクラス
//==================================================================
class CMyShip : public CMover
{
public:

	// new operator, delete operator
	void* operator new( size_t t )
	{
		return operator_new( t, Game->MyShipList );
	}
	void operator delete( void* p )
	{
		return operator_delete( p, Game->MyShipList );
	}

	// Constructor
	CMyShip( float x, float y )
	: CMover( Game->MyShipList, x, y )
	{
	}

	// Move, Draw
	virtual bool Move();
	virtual void Draw();
};

コード:

//MyShop.cpp

#include "Main.h"
#include "MyShip.h"


//==================================================================
// Move
// 移動
//==================================================================

bool CMyShip::Move()
{
	// Moving range
	static const float MaxX=46, MaxY=46;

	static const float sqrt2 = 1/sqrt( 2.0f );

	// speed
	float vx = 0.8f, vy = 0.8f;

	// Get InputState
	const CInputState* is = Game->GetInput()->GetState(0);

	// move
	if( is->Left ) {
		vx = -vx;
	}
	else if( is->Right )
	{
	}
	else
	{
		vx = 0;
	}

	if( is->Up ) vy = -vy; else if( !is->Down ) vy = 0;

	if( vx != 0 && vy != 0 )
	{
		vx *= sqrt2;
		vy *= sqrt2;
	}

	X += vx;
	Y += vy;

	if( X < -MaxX ) X = -MaxX; else if( MaxX < X ) X = MaxX;
	if( Y < -MaxY ) Y = -MaxY; else if( MaxY < Y ) Y = MaxY;

	return true;
}

//==================================================================
// Draw
// 描画
//==================================================================
void CMyShip::Draw()
{
	Game->GetGraphics()->SpriteDraw( Game->MyShip->GetTexture(), X, Y );
}

コード:

// Mover.h   cppはないです

#pragma once

#include "Task.h"

//==================================================================
// Moving objects class
// 移動物体のクラス
//==================================================================

class CMover : public CTask
{
public:

	// Coordinate
	float X, Y;

	// Constructor
	CMover( CTaskList* list, float x, float y )
	: CTask( list ), X( x ), Y( y )
	{
	}

	// Move
	// Override this virtual functoin
	// Moving objects after the move to erase = false.
	// Not erase = true.
	virtual bool Move() { return true; }

	// Draw
	virtual void Draw() {}
};
こんなもんですかね・・・
よろしくお願いします。

おっく

Re: タスククラスの例外

#9

投稿記事 by おっく » 9年前

コード:

// タスクをアクティブタスクリストに挿入する
//挿入要素の繋ぎ処理
{
	//自身の前後を繋ぐ
	this.Prev=TaskList->ActiveTask->Prev;
	this.Next=TaskList->ActiveTask;

	//自身を参照するのは、ActiveTask->Prevと、ActiveTask->Prev->Next
	ActiveTask->Prev->next = this;
	ActiveTask->Prev=this;
}
多分こんな感じの修正でコンパイルエラーは解消すると思う。
でも苦しむだろうな。
言ってやりたい事は沢山ありますが、あとは分かるな?

アバター
lriki
記事: 88
登録日時: 9年前

Re: タスククラスの例外

#10

投稿記事 by lriki » 9年前

新しく貼っていただいたコードの部分じゃないのでちょっと恐縮ですけど、
タスクリストを作っているところに怪しいところをみつけました。
MyShipList = new CTaskList( sizeof( MyShip ), 10 );
 ↓
MyShipList = new CTaskList( sizeof( CMyShip ), 10 );
に変えてみてください。

CMyShip じゃなくて MyShip (多分ポインタ変数?) のサイズをみてます。

Suikaba
記事: 194
登録日時: 9年前

Re: タスククラスの例外

#11

投稿記事 by Suikaba » 9年前

>>おっくさん
どうもです。自分自身レベルが低いので、日々精進いたします。

>>梨樹さん
あ、ほんとだ・・・(笑)
どうもすいません。自分のミスでした。すんなりコードとおりました。

お2人とも、ありがとうございました。

Suikaba
記事: 194
登録日時: 9年前

Re: タスククラスの例外

#12

投稿記事 by Suikaba » 9年前

解決しました

閉鎖

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