「std :: bad_alloc」:私はあまりにも多くのメモリを使用していますか?
質問
メッセージ:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
私はGDBのバックトレースを見ましたが、これは自分自身を実装した最低レベルの方法です。
/*
* get an array of vec3s, which will be used for rendering the image
*/
vec3 *MarchingCubes::getVertexNormalArray(){
// Used the same array size technique as getVertexArray: we want indices to match up
vec3 *array = new vec3[this->meshPoints.getNumFaces() * 3]; //3 vertices per face
int j=0;
for (unsigned int i=0; i < (this->meshPoints.getNumFaces() * 3); i++) {
realVec normal = this->meshPoints.getNormalForVertex(i);
// PCReal* iter = normal.begin();
if (normal.size() >= 3) {
array[j++] = vec3(normal[0], normal[1], normal[2]);
}
cout << i << " ";
}
return array;
}
上記のカウトステートメントは、7000回以上の反復後に終了することを示しています。上記の関数は、アプリケーションの終わり近くに1回だけ呼ばれます。上記を呼び出す前に非常によく似た関数を呼び出しますが、それは問題を引き起こしません。
解決 2
私の問題はそれであることが判明しました this->meshPoints.getNormalForVertex(i)
長さがより少ないアレイ(またはベクトル、私は覚えていない)にアクセスします this->meshPoints.getNumFaces() * 3
. 。そのため、範囲外にアクセスしていました。
他のヒント
(コメントから移動/拡大)
あなたはそれを扱うことなく毎回新しい配列を割り当てるので、あなたはそれを返すことなくシステムにメモリを尋ね続け続けます。最終的にはヒープのスペースが仕上げられ、次の割り当てであなたが得るのはすべてです std::bad_alloc
例外。
「Cスタイル」の解決策は、あなたがもうそれを必要としないときにそのようなメモリを扱うことを忘れないでください( delete[]
)、しかし、これは(1)エラーが発生しやすいです(たとえば、関数内に複数の戻りパスがある場合は考えてください)と(2)潜在的に例外を維持します(例外がある場合、すべての命令が潜在的なリターンパスになります!)。したがって、この方法は避ける必要があります。
慣用C ++ソリューションはどちらも使用します スマートポインター - ポインターをカプセル化して、それらが破壊されたときに関連するメモリを扱う小さなオブジェクト - または標準コンテナ、それは多かれ少なかれ同じことをしますが、コピーセマンティクスといくつかのベルとホイッスル(その内部のアレイのサイズを保存することを含む) 。
負の長さの配列を割り当てようとするこのエラーが発生しました。
double myArray = new double [-9000];
それが誰にでも役立つ場合に備えて。