以下のコードがメモリリークの原因になるのではないかと思いますか?このコードはメモリリークを避けるでしょうか?
char **a;
a = new char* [m];
a[0] = new char[m * n]; // allocate all need
for(int i=1; i<m; i++)
{
a[i] = a[i-1] + n;//allocate every pointer
}
delete[] a[0];
delete[] a;
以下のコードがメモリリークの原因になるのではないかと思いますか?このコードはメモリリークを避けるでしょうか?
char **a;
a = new char* [m];
a[0] = new char[m * n]; // allocate all need
for(int i=1; i<m; i++)
{
a[i] = a[i-1] + n;//allocate every pointer
}
delete[] a[0];
delete[] a;
これは問題ありません。 2つの割り振りと、2つの割り振り解除と、一致するタイプと一致するポインターがあります。メモリが漏れません。
コードが完了して実行されると、メモリリークは発生しません。それでも例外がスローされた場合は、リークします。
'a [0] = new char [m * n];'という行がスローされます。メモリが割り当てられた後に実行される他のすべてのステートメントはno-throwです。 –
VS2010で試してみましたが、正常です。 – RayZy
第2のnew
が失敗すると、例外がスローされ、最初の割り当ては削除されず、リークが発生します。
これを避ける最も良い方法は、手動でメモリを管理するのではなく、リソース管理クラスを使用することです。この場合、std::vector
は最高のようになります。
std::vector<char> memory(m * n);
std::vector<char*> pointers;
pointers.reserve(m);
pointers.push_back(&memory.front());
for (int i = 1; i < m; ++i) {
pointers.push_back(pointers.back() + n);
}
さて、デストラクタは、コードが正常に完了するか、または例外をスローするかどうか呼び出されることが保証されているので、いずれの場合には、リークはありません。
ベクトルコンテナは私たちに大きな利便性を与えますが、私はそれに同意しますが、効率の面ではそれはありませんか? – RayZy
最適化が無効になっていないか、実装が非常に悪い場合を除き、手動管理のアレイと同じくらい効率的でなければなりません。私のコードは、2つのメモリ割り当て、 'm'割り当て、2つの割り当て解除とほぼ同じように動作するはずです。すべての関数呼び出しはインライン化する必要があります。例外の管理方法に応じて、例外安全のためのコストがかかるかもしれませんが、漏れを修正しようとしたにもかかわらずコストがかかります。 –
割り当てが失敗し、例外がスローされない限り。あなたが本当に必要でない限り、手動割り当てを使わないでください。 –
新しいスローが発生した場合のOOM状況を気にするなら、それは正しいです。私はスローしない埋め込みアロケータに慣れています。彼らはちょうどボックスをハードリセットしました:-) – user9876
これは本当の、醜いコードだと思いますが、私はちょうどこの1回用量の作業を確実にしたいです – RayZy