Exceptional C++ では、Herb Sutter が項目 35 でガイドラインとして次のように書いています。
無料ストア (新規/削除) を使用することをお勧めします。ヒープ (malloc/free) を使用しないでください。
どして私がこんな事に?
new
実装が を使用して実装することを選択した場合、malloc
おそらくオーバーヘッドが発生するため、パフォーマンスに関する限り、これは悪いアドバイスのように見えます。
Exceptional C++ では、Herb Sutter が項目 35 でガイドラインとして次のように書いています。
無料ストア (新規/削除) を使用することをお勧めします。ヒープ (malloc/free) を使用しないでください。
どして私がこんな事に?
new
実装が を使用して実装することを選択した場合、malloc
おそらくオーバーヘッドが発生するため、パフォーマンスに関する限り、これは悪いアドバイスのように見えます。
C++のnew
anddelete
キーワードは通常、malloc
andの観点から実装されfree
ますが、異なることを行うように設計されています。
C++ で言うと、
new T(/* args */)
C++ は次のことを行います。
T
。std::bad_alloc
メモリが利用できない場合は最終的にオブジェクトをスローします。T
そのメモリ ブロックで型のオブジェクトの構築を試みます。T
例外がスローされた場合、メモリの割り当てを自動的に解除します。を使用するだけの場合malloc
、これらの手順をすべて手動で行う必要があり、非常に困難です。次のようになります。
T* memory = nullptr;
while (true) {
memory = static_cast<T*>(malloc(sizeof(T)));
if (memory != nullptr) break;
std::get_new_handler()();
}
try {
new (memory) T(/* args */);
} catch (...) {
free(memory);
throw;
}
ここで私が見落としたニュアンスが他にもいくつかあります ( のoperator new
代わりに呼び出すmalloc
、サイズがゼロのリクエストを処理するなど) が、new
とmalloc
がどのように異なるかを説明するのに役立つことを願っています。
では、なぜnew
overを使用する必要があるのmalloc
でしょうか。いくつかの理由があります。
はるかに安全です。 null ポインターの戻り値の型をチェックするのをmalloc
忘れたり、間違った量のストレージ スペースを要求したり、オブジェクトでコンストラクターを呼び出すのを忘れたり、コンストラクターが例外をスローした場合にメモリの割り当てを解除するのを忘れたりする可能性があります。など
より型安全です。 malloc
を返しますvoid*
。これはメモリ ブロックへの単なるポインタです。を使用malloc
すると、ポインターを適切な型にキャストする必要があり、後でエラーが発生する可能性があります。
カスタマイズが可能です。 特定の型はオーバーロードoperator new
して、プールされたアロケーターやより高速なメモリの特定の部分から、または使用パターンを最適化するカスタム アロケーターを使用するなど、通常とは異なる方法でメモリを要求します。これにより、とT
を定義するだけで、タイプのオブジェクトにメモリが動的に割り当てられるすべての時間を自動的にカスタマイズできます。を使用する場合は、プログラム全体ですべてのメモリ割り当てサイトを追跡する必要があります。operator new
operator delete
malloc
とはいえ、 にはいくつかの利点がありmalloc
ます。自明なオブジェクト (データを保持するだけのプリミティブや構造体など) であるオブジェクトを割り当てていることが確実にわかっている場合は、malloc
. malloc
も使用できますがrealloc
、使用できfree
ません。std::vector
しかし、正直なところ、このような場合は単にorを使用したほうがよいでしょう。std::array
なぜなら、それらはより安全で、デバッグが容易であり、適切なコンパイラ サポートがあれば、積極的に最適化される可能性が高いからです。
お役に立てれば!