プログラムを実行中に、std::bad_allocという例外が返されました。
std::bad_allocについて調べたところ、newの確保に失敗した時に返される例外であるということがわかり、
newを使っている箇所全てにtry~catchブロックを作って、失敗した箇所を探そうとしたのですが、
どのブロックにも引っかかりませんでした。
ここで質問なのですが、std::bad_allocはnew使用時以外でも返される場合があるのでしょうか?
また、std::vectorや、std::list, std::mapなども返される可能性はあるでしょうか?
そして、std::bad_allocを予防するには何か方法があるのでしょうか?
コンパイラはVC++2008EEで、PCのメモリは4GBであり、(OSがvista32bitなので、実質3GBでしょうか?)
少なくともnewでのメモリ不足は無いと考えられます。
std::bad_allocについて
Re:std::bad_allocについて
STL ライブラリ全てのメモリ確保に関して std::bad_alloc 例外を返すことがあります。
(環境によっては例外を出さないものもあります)
今回の場合、 new で確保する時に配列数などに異常な値を渡され、 std::bad_alloc 例外が発生しているのではないでしょうか。
(未初期化の値を渡している場合は高確率で発生します)
もしかしたら、累積的なメモリリークによるメモリ確保の失敗かもしれません。
(ちなみに throw を使って自ら std::bad_alloc 例外を発生させることも可能です)
(環境によっては例外を出さないものもあります)
今回の場合、 new で確保する時に配列数などに異常な値を渡され、 std::bad_alloc 例外が発生しているのではないでしょうか。
(未初期化の値を渡している場合は高確率で発生します)
もしかしたら、累積的なメモリリークによるメモリ確保の失敗かもしれません。
(ちなみに throw を使って自ら std::bad_alloc 例外を発生させることも可能です)
Re:std::bad_allocについて
作成しているプログラムというのが、戦略シミュレーションゲームなのですが、
マップによって、例外が返されるかが違ってきます。
ですが、マップが大きいほど、ユニットが多いほど例外が発生しやすいことが分かったので、
単純にメモリを使い切ったのではないかと思ったのですが、
クラスのインスタンスがnewで確保されていれば、メンバ変数もビープ領域に置かれますよね?
そうすると、メモリ不足とは考えられないのですが・・・。
ちなみに、newで配列を確保したりはしていません。
敵が攻撃される時に発生する爆発アニメーションを消したところ、
例外は発生しなかったのですが、そのアニメーションの処理にはnewもSTLも使っていません。
ということは、やはりメモリ不足なのでしょうか?
マップによって、例外が返されるかが違ってきます。
ですが、マップが大きいほど、ユニットが多いほど例外が発生しやすいことが分かったので、
単純にメモリを使い切ったのではないかと思ったのですが、
クラスのインスタンスがnewで確保されていれば、メンバ変数もビープ領域に置かれますよね?
そうすると、メモリ不足とは考えられないのですが・・・。
ちなみに、newで配列を確保したりはしていません。
敵が攻撃される時に発生する爆発アニメーションを消したところ、
例外は発生しなかったのですが、そのアニメーションの処理にはnewもSTLも使っていません。
ということは、やはりメモリ不足なのでしょうか?
Re:std::bad_allocについて
一度タスクマネージャを起動し、パフォーマンスタブを表示した状態で実行してみてください。
この状態で例外が発生したときにメモリ使用率のグラフが上端までいっていたらメモリ不足で、
そうでない場合は異常なサイズのメモリ確保を行おうとした可能性があります。
(どこかの処理でバグが存在している可能性)
malloc 関数でも、デバッグ版などであれば内部的に例外を出す場合があります。
もしかしたらその辺りかもしれません。
あと、仮想メモリが標準で有効になっているはずなので、
普通メモリを使い切る前後に動作が重くなるなどの予兆が出るはずです。
ちなみにメモリリーク対策は行っていますか?
crtdbg.h をインクルードし、起動直後に
この状態で例外が発生したときにメモリ使用率のグラフが上端までいっていたらメモリ不足で、
そうでない場合は異常なサイズのメモリ確保を行おうとした可能性があります。
(どこかの処理でバグが存在している可能性)
malloc 関数でも、デバッグ版などであれば内部的に例外を出す場合があります。
もしかしたらその辺りかもしれません。
あと、仮想メモリが標準で有効になっているはずなので、
普通メモリを使い切る前後に動作が重くなるなどの予兆が出るはずです。
ちなみにメモリリーク対策は行っていますか?
crtdbg.h をインクルードし、起動直後に
_CrtSetDbgFlag(_CRTDBG_ALLOC_MEM_DF | _CRTDBG_LEAK_CHECK_DF);を呼んでおけば、プログラム終了時に開放されなかったメモリをレポート(出力)してくれます。
Re:std::bad_allocについて
>失敗した箇所を探そうとしたのですが
ということは、まだ例外が発生した場所は見つかっていないのでしょうか?
VisualStudioのデバッガを使えば例外を出した時点で、止めてくれると思うのですが。
方法 : 例外がスローされたときに中断する
ttp://msdn.microsoft.com/ja-jp/library/d14azbfh(VS.80).aspx
Re:std::bad_allocについて
いろいろと仕様を変えてしまったら、例外が発生しなくなってしまったので、
原因の追究が出来なくなってしまいました。
根本的な解決でないですが、一応解決したので、このスレッドは終了とします。
ありがとうございました。
原因の追究が出来なくなってしまいました。
根本的な解決でないですが、一応解決したので、このスレッドは終了とします。
ありがとうございました。