C++によるタスクシステムに関する質問(少々面倒です)

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

C++によるタスクシステムに関する質問(少々面倒です)

#1

投稿記事 by AC » 16年前

こちらでは、はじめて質問させていただきますACです。
C++については大体基本はわかってるぐらいの知識です。

DxLibを使用してゲームのひな形でも作ろうなと思い、C++でリストを使ってタスクシステムを実装したのですが、一部挙動が不明のところがあり、いくら考えても分からず気になって気になってしょうがないので、質問するしだいに至りました。
ここには全てを書きにくいいのでソースをアップしましたのでそちらを参照しながら見ていただけたらと思います。
アドレス:http://www1.axfc.net/uploader/He/so/163203
ダウンロード&解凍パス:sitsumonyo
既に実行できる状態のVC2008のプロジェクトです(DxLibのインクルードとリンクはそちらの方でお願いします)。
まず、タスクシステムについては、これはhttp://www.tnksoft.com/さんのサイトの
http://www.tnksoft.com/reading/classgam ... 01/011.php
を参考にしています(ほぼまんまですが・・・)。
タスクに関する全処理はMaster.cppに書かれています。

さて本題ですが、不明な点はOpening.cppにあります。
簡単にいえば使いたいときに AddTask(new クラス名()...) でタスクに追加して、いらなくなったら RemoveTask(インスタンス) で削除すればよいのですが、Opening.cpp内でRemoveTask(this)のようにしてタスクを消したところ、エラーが出てしまいました(色々試しましたがOpening.cpp内でなくてもエラーが起こるようです)。
リストの要素のerase時にエラーが出てるらしく、どうもイテレータによる参照が変な感じであることがわかったのですが、なぜおかしくなるのかがどうしてもわかりませんでした。

少々面倒な質問ですが、エラーのでる理由のわかる方は教えていただけたら幸いです。よろしくお願いします。

GPGA

Re:C++によるタスクシステムに関する質問(少々面倒です)

#2

投稿記事 by GPGA » 16年前

削除後のイテレータを設定し直していないためです。

× TaskList.erase(iter);
○ iter = TaskList.erase(iter);

御津凪

Re:C++によるタスクシステムに関する質問(少々面倒です)

#3

投稿記事 by 御津凪 » 16年前

恐らく、自分自身を RemoveTask したあとは既にインスタンスは delete されているので、その後の自分自身に対する処理はエラーになります。

対処は、自分自身が RemoveTask した後に直ぐに出るか、 removeTask をタスクループ外で呼び出すか、
タスクシステムの構造を変えるかのどれかになります。

GPGA

Re:C++によるタスクシステムに関する質問(少々面倒です)

#4

投稿記事 by GPGA » 16年前

あ、すぐreturnしているのか。直接的な関係はなさそうですね。
もう少し調べてみます。

GPGA

Re:C++によるタスクシステムに関する質問(少々面倒です)

#5

投稿記事 by GPGA » 16年前

御津凪さんの言うとおりですね。

今回の場合COpening01::Execメソッド内の
++timer;
のところで開放済みのクラスのメンバにアクセスしているため
アクセス違反を起こしています。

AC

Re:C++によるタスクシステムに関する質問(少々面倒です)

#6

投稿記事 by AC » 16年前

御津凪さん、GPGAさん、ご解答ありがとうございます。

まさしくおっしゃる通りでした。
サンプルだしー、という感じで何気なく書いてしまったtimer++が原因でしたorz。
ひとまず解決です。
ありがとうございました。

でも、それならまたいくつか疑問に思う点がありまして、
1.なぜこのエラーはプログラム終了時に発生するのか(delete時には発生してないようですので)
2.アップした質問用プロジェクトは作製途中の元ソースのエラー探しの過程でできたものでもあるのですが、元のソースの方ではVC側からはxmemory(リスト関連のヘッダ?)というところの
void deallocate(pointer _Ptr, size_type)
		{	// deallocate object at _Ptr, ignore size
→		::operator delete(_Ptr);
		}
でエラーが起きているといわれるのですが、これは何を意味しているのか

の2点がよく分かりません。
2の方は元ソースの方はアップしてないので情報不足でしたらスルーしてくださって構いません。
もしよかったら回答のほうよろしくお願いします。

御津凪

Re:C++によるタスクシステムに関する質問(少々面倒です)

#7

投稿記事 by 御津凪 » 16年前

1.については、deleteの処理自体は正常に処理され、
その後deleteされたthisポインタを持った状態で関数から戻ってきているので、
deleteされたthisポインタを参照してしまうとアクセス違反エラーになります。
もしエラーにならなくても、終了時に何らかの形で(ヒープが壊れているとか)エラーを出します。
(後者が該当する原因かと)

2.は1.によるものだと思われます。

ちなみに、ヒープが壊れているというのは、確保した領域の前後(あるいは確保していた領域)に
書き込みが行われたことが原因となります。

AC

Re:C++によるタスクシステムに関する質問(少々面倒です)

#8

投稿記事 by AC » 16年前

御津凪さん、丁寧なご回答ありがとうございます。
完全に納得いたしました。

これにて全て解決ということにさせていただきます。
本当に勉強になりました。

ご回答してくださった皆様ありがとうございました。

閉鎖

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