45

私のプログラムにはかなり深刻なバグがあります - new() を時々呼び出すと、bad_alloc がスローされます。

bad_alloc で見つけることができるドキュメントから、次の理由でスローされるようです。

  1. コンピューターのメモリが不足すると (これは確実に発生していません。4GB の RAM があり、5MB 未満 (タスクマネージャーでチェック済み) を使用している場合、プログラムは bad_alloc をスローし、バックグラウンドで何も実行されていません)。

  2. メモリが断片化しすぎて新しいブロックを割り当てられなくなった場合 (これもありそうにありません。これまでに割り当てた最大サイズのブロックは約 1KB であり、クラッシュが発生する前に 100 回以上実行されることはありません)。

これらの説明に基づいて、実際には bad_alloc がスローされる可能性のある場所はどこにもありません。

ただし、実行中のアプリケーションは複数のスレッドを実行しているため、問題の原因となっている可能性があります。すべてのオブジェクトを 1 つのスレッドでテストすると、すべてがスムーズに機能しているように見えます。ここで起こっていると私が考えることができる唯一の他のことは、同時に複数の場所で new() を呼び出すことによって引き起こされるある種の競合状態である可能性がありますが、その動作を防ぐためにミューテックスを追加しようとしました無効。

プログラムは数百行あり、問題が実際にどこにあるのかわからないため、投稿するコードスニペットがあるとしても、どのコードスニペットを投稿すればよいかわかりません。代わりに、この種のことをテストするのに役立つツールがあるかどうか、またはこの問題を解決するのに役立つ一般的な戦略があるかどうか疑問に思っていました.

私は Microsoft Visual Studio 2008 を使用しており、スレッド化には Poco を使用しています。

4

6 に答える 6

26

bad_alloc は、ヒープが割り当て元のメモリ プールを管理するために使用するポインターを上書きするバグがある場合にもスローされる可能性があります。

その最も一般的な原因は、割り当てられたメモリ ブロックの末尾を超えて (または開始前ですが、あまり一般的ではありません) 書き込みを行っていることです。解放されたメモリ ブロックへの書き込みも同様に一般的です。これは、ヒープの破損と呼ばれます。

また、Windows の 32 ビット プロセスのアドレス空間は最大で 2GB (大きなアドレスを認識するプログラムの場合は 3GB) であることに注意してください。これは、インストールした RAM の量に関係なく、メモリは仮想メモリであり、RAM が 1GB しかない場合でも、アドレス空間がなくなるまで割り当ては失敗しません。

ここでは、C++ でのメモリ破損についての良い議論がありますhttp://www.eventhelix.com/RealtimeMantra/Basics/debugging_software_crashes_2.htm

于 2010-03-20T04:45:23.097 に答える
23

もう1つの考えられる問題は、プログラムが5MB未満を使用していると述べている一方で、割り当てようとしているスペースの量については言及していないことです。割り当てサイズを決定するために使用する値を破壊する競合状態が発生している可能性があり、37TBまたはそのようなナンセンスを割り当てようとしている可能性があります。

特に可能性は低いと思いますが、確認する価値があります。

于 2010-03-20T04:56:10.560 に答える
3

いくつかの説明:

Windows のすべてのプロセスは 4GB の仮想メモリを取得します。そのうちの 2GB はユーザー空間用で、残りはカーネル空間用です。4GB の RAM は仮想メモリには寄与しませんが、物理メモリ用です。

2GB のメモリには、すべての EXE、DLL がロードされ、1.6 ~ 1.7GB のメモリ割り当てに使用できるのはほとんどありません。このメモリに割り当て用の連続したメモリがない場合、メモリの割り当ては失敗します。

于 2010-03-20T04:41:27.713 に答える
1

bad_alloc は、他のコードからもスローされる可能性があります。

STLコンテナで使用するために設計された制限メモリプールで使用されるのを見てきました。サイズ制限に達すると、bad_alloc がスローされ、ソフトウェアはそれを処理する必要がありました。

于 2010-04-03T02:41:01.680 に答える
1

私は実際にこの問題を以前に抱えていましたが、プロジェクトをクリーニングして再構築することで修正されました。奇妙な動作が発生した場合は、常に試してみる価値があります (コンパイルに数時間かかる巨大なプロジェクトでない限り)。

于 2013-08-29T15:21:25.287 に答える