std::out_of_rangeについて

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

std::out_of_rangeについて

#1

投稿記事 by guzoku » 10年前

コンピュータ系専門学校に入学し、C言語及びC++を授業で学び始め7~8ヶ月の者です。
1~2ヶ月前ぐらいにc++へ移行し、現在c++ 14歳から始めるゲームプログラミングという本に記載されている
サンプルプログラムをとりあえず組んで、それを指定された機能を追加したり変更したりすることを冬休みの課題で指定されているのですが、
サンプルプログラムを説明通りに組み始めて、5章の終盤でどうしても詰まってしまうところがあります。

コンパイルは正常に終了するのですが、プログラムを実行し、
敵が弾を出そうとした瞬間、std::out_of_rangeの例外エラーが発生し、正常に動作しなくなります。
画像
ネットでググってみたのですが、原因などが全く見つかりませんでした。
エラーの内容的にどこかの変数の値がおかしくなっているのかと思い、
本の内容と実際に打ったソースを見比べましたが、見た限り間違ったところがなく、
詰まっている状況です。

現時点で分かっていることは、
・teki.cppのtamamove();を呼びださなければ例外エラーは起きない
・しかし自機の弾が何もしなくても画面上に出ている、キー操作を受け付けない、敵の弾挙動が本来と違う、
 など様々な異常がある。

std::out_of_rangeの他にいろいろ異常が出ているので、
見落としている初歩的なミスがあるのかもしれませんが、
よろしくお願いします。
ちなみにコンパイラはMicrosoft Visual Studio 2013 Professional内のVisual C++ 2013を使用しております。

ソースファイル、サンプルプログラムのデータ、プロジェクトファイルはこちらになります。
http://file.immigrants.jp/c++/testgame1.zip

Rittai_3D
記事: 525
登録日時: 12年前

Re: std::out_of_rangeについて

#2

投稿記事 by Rittai_3D » 10年前

ソースコードを読んでいませんし、"c++ 14歳から始めるゲームプログラミング"という本も読んだことがないので推測です。

配列を使用しているなら、添え字に変な値(負の数や要素数以上の数)が入っていないかどうかを調べてみてください。
また、std::vector や std::deque などを使用していて、添え字でアクセスしている場合も同様に調べてください。
ネットでググってみたのですが、原因などが全く見つかりませんでした。
エラーの内容的にどこかの変数の値がおかしくなっているのかと思い、
本の内容と実際に打ったソースを見比べましたが、見た限り間違ったところがなく、
詰まっている状況です。
out_of_range 原因でしらべた結果です。
http://yukki99.studio-web.net/stage/cpp_1-11.html一ページめにあったサイトです。ここに原因が書いてあります。

見た限り間違いがないはずがありません。間違いがなければエラーは発生しません。
現時点で分かっていることは、
・teki.cppのtamamove();を呼びださなければ例外エラーは起きない
・しかし自機の弾が何もしなくても画面上に出ている、キー操作を受け付けない、敵の弾挙動が本来と違う、
 など様々な異常がある。
tamamove()を呼ばなければエラーが出なくなるのなら、そこに原因があるはずです。
そこで徹底的に範囲外アクセスが起きていないかどうか調べてください。
初心者です

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: std::out_of_rangeについて

#3

投稿記事 by みけCAT » 10年前

デバッグ用コードを入れてテストした所、
teki.cppの116行目で呼び出されているdraw関数において、
animdraw.cppの26行目でapidとしてaplist.size()以上の値が渡されているため、範囲外アクセスとなっているようです。
このdraw関数を呼び出されているのはおそらくteki.cppの90行目でpush_backされたnewpodのanimメンバが指す先であり、
すなわちtekianimです。
よって、draw関数でapidが適切な値かをチェックしていないこと及び、
teki.cppの7~25行目のloadFiles関数でtekianimに適切に画像を登録していないことが原因だと思います。

テストコードを追加したソースコードを添付します。
元のデータのtestgame1\Release\mediaディレクトリをexeファイルを実行する際のカレントディレクトリにコピーしてから実行してください。
試していませんが、シンボリックリンクでもいいかもしれません。
添付ファイル
testgame1_build.zip
テストコード入りソースコードとバイナリ
(2.14 MiB) ダウンロード数: 112 回
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: std::out_of_rangeについて

#4

投稿記事 by みけCAT » 10年前

guzoku さんが書きました:キー操作を受け付けない
gameframe.cppの61行目で

コード:

idouryou[1] = i / 16.67*frametime;
という記述があり、常にidouryou[1]に代入しています。

コード:

idouryou[i] = i / 16.67*frametime;
とするべきだと思います。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

アバター
みけCAT
記事: 6734
登録日時: 14年前
住所: 千葉県
連絡を取る:

Re: std::out_of_rangeについて

#5

投稿記事 by みけCAT » 10年前

guzoku さんが書きました:自機の弾が何もしなくても画面上に出ている
ステージを開始するためにZキー(PAD_INPUT_A)を押したことによって自機の弾が発射されたため、画面上に出ているのだと思います。
「何もしていないのにおかしくなった!」というのは、ネタとしてよく聞きますね。
複雑な問題?マシンの性能を上げてOpenMPで殴ればいい!(死亡フラグ)

guzoku
記事: 4
登録日時: 10年前

Re: std::out_of_rangeについて

#6

投稿記事 by guzoku » 10年前

みけCAT さんが書きました:デバッグ用コードを入れてテストした所、
teki.cppの116行目で呼び出されているdraw関数において、
animdraw.cppの26行目でapidとしてaplist.size()以上の値が渡されているため、範囲外アクセスとなっているようです。
このdraw関数を呼び出されているのはおそらくteki.cppの90行目でpush_backされたnewpodのanimメンバが指す先であり、
すなわちtekianimです。
よって、draw関数でapidが適切な値かをチェックしていないこと及び、
teki.cppの7~25行目のloadFiles関数でtekianimに適切に画像を登録していないことが原因だと思います。
適切なアドバイスありがとうございます。
仰るとおり、teki.cppの7~25行目を見なおしたところ、例外エラーが発生せず正常に動作しました。
みけCAT さんが書きました:
guzoku さんが書きました:キー操作を受け付けない
gameframe.cppの61行目で

コード:

idouryou[1] = i / 16.67*frametime;
という記述があり、常にidouryou[1]に代入しています。

コード:

idouryou[i] = i / 16.67*frametime;
とするべきだと思います。
こちらもアドバイス通りに変更したところ問題なく動くようになりました。
生徒全員分の書籍が無く、僕をはじめPDFで書籍が配布されている生徒がおり、
PDFではドットとコロン、1とiの判別が困難だったため、
誤読してしまったんだと思います。

結果として誤読が原因のエラーだったようです。
もう少し精進します。
皆さんありがとうございました。

閉鎖

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