0

私は他の誰かが作成したプログラムで作業しています。私はコーディングの経験はかなりありますが、C++ でのコーディングの経験はそれほど多くないので、ここで多くの「実行による学習」を行っています。そのため、プログラムは安定しているように見えたので、私はそれに取り組み始めました。これには、主にプログラムの小さな部分に小さな変更を加えることが含まれていました。最近、パフォーマンスの最適化を行いましたが、これも安定しているように見えましたが、2 日前に何かを変更したところ、クラッシュが発生し続けました。そのため、変更を元に戻しましたが、それでもクラッシュが発生しました。アプリケーション検証ツールとグローバル フラグを使用して、ページ ヒープをアクティブにし、ヒープ関連のすべてをチェックして、これらの問題の原因を突き止めました。そのため、デバッガーは常に「std::bad_alloc」エラーでクラッシュしていました。

ここで私の質問: Application Verifier を有効にしたこの bad_alloc クラッシュは、プログラム内のバグの兆候であると確信できますか? Application verifier を使用すると、プログラム自体が大量のメモリ (約 1 ~ 1.1 GB) を使用しますが、それ以上使用することはありません。合計システム メモリは多くても 80 ~ 90% 使用されているため、空き容量が少なすぎるために実際に割り当ての問題が発生することはないと思います。どう思いますか?

4

3 に答える 3

2

いいえ、プログラムに未定義の動作が含まれる可能性があるため、任意の C++ プログラムの内容について完全に確信することはできません (実際、目前の問題とは関係ないかもしれませんが、ほぼ確実にそうです)。とはいえ、通常の原因はstd::bad_allocメモリを割り当てられないことです。

std::set_new_handlerを使用して custom を設定new_handlerし、そこにブレークポイントを配置します。ブレークポイントがトリガーされた場合、問題はほぼ確実にメモリを割り当てることができないことです (この時点でのプログラムの状態は、問題のデバッグに役立つ可能性があります)。

于 2013-02-22T17:56:10.453 に答える
1

デフォルトでは、Windows for x86 の 32 ビット プロセスは2GB のアドレス空間(全アドレス空間の下半分) に制限されています。

プログラムが大量の割り当てと割り当て解除を実行する場合、またはプログラムが大量の連続した割り当てを必要とする場合、プログラムが 1.1GB のワーキング セットしか使用していない場合、割り当てを処理するための連続したアドレス空間が不十分になる可能性は十分にあります。

(私は数年前、アドレス空間によって厳密に制約された大規模なプロジェクトに取り組みました。1.2 ~ 1.4 GB のワーキング セットで「メモリ不足」になるのはよくあることです。)

ページ ヒープは、ほとんどの割り当てが通常よりもはるかに大きいため、この問題をより深刻にします。

于 2013-02-22T17:54:08.773 に答える
0

バイナリが std::bad_alloc でクラッシュしたときに受け取ったスタックを調べる必要があります。

通常、これは がnewメモリを割り当てることができなかったためです。スタックを使用すると、要求されたメモリの量を知ることができるはずです。また、それが奇妙なことを意味する場合 (たとえば、「3Go を割り当ててください!」)、バグがどこにあるかがわかります。

あなたの質問を読むときは明確ではありませんが、プロセスが利用可能な仮想メモリの最大 80% から 90% を使用することを意味している場合、おそらくメモリが断片化されており、オブジェクトを割り当てようとしています。大きすぎて残りの空きメモリチャンクに収まりません...したがって、プロセスがまだ遊ぶメモリを持っているにもかかわらず、割り当てが悪くなります。

コードを検索して、コードの一部が手動で bad_alloc をスローするかどうかを確認することもお勧めします。

于 2013-02-22T17:54:30.267 に答える