C++でnew
に対してmalloc
を使用するメリットを理解しています。しかし、プリミティブデータタイプ(非配列)-int
、float
などの特定のケースでは、malloc
を使用する方がnew
よりも高速ですか?
ただし、プリミティブの場合でもnew
を使用することをお勧めしますが、delete[]
を使用できるように配列を割り当てる場合は、.
しかし、配列以外の割り当ての場合、int
のコンストラクター呼び出しはないと思います。 new
演算子はメモリを割り当て、割り当てられているかどうかを確認してからコンストラクタを呼び出します。しかし、プリミティブの配列以外のヒープ割り当てについては、malloc
よりもnew
を使用する方が良いですか?
お知らせ下さい。
C++ではmalloc
を使用しないでください。低レベルのメモリ管理プリミティブを実装しているのでない限り、new
を使用しないでください。
推奨事項は次のとおりです。
自問してみてください: "動的メモリ割り当てが必要ですか?"。多くの場合、あなたはそれを必要としないかもしれません-ポインタよりもvaluesを好み、スタックを使用してみてください。
動的なメモリ割り当てが必要な場合は、「割り当てられたメモリ/オブジェクトを誰が所有するか」を自問してください。
単一の所有者のみが必要な場合(これは非常に可能性があります)、 _std::unique_ptr
_ を使用する必要があります。これは、new
/delete
をゼロコストで抽象化したものです。 (別のデアロケーターを指定できます。)
所有権を共有する必要がある場合は、 _std::shared_ptr
_ を使用する必要があります。これは、アトミック操作と追加の「制御ブロック」を使用してすべての所有者を追跡するため、ゼロコストの抽象化ではありません。
特に配列を扱う場合、標準ライブラリは手動のメモリ管理を必要としない2つの強力で安全な抽象化を提供します。
_std::array<T, N>
_ :N
タイプのT
要素の固定配列。
_std::vector<T>
_ :タイプT
の要素のサイズ変更可能な配列。
_std::array
_および_std::vector
_は、「配列の必要性」の99%をカバーする必要があります。
さらに重要なこと:標準ライブラリは _std::make_unique
_ と _std::make_shared
_ を提供しますが、これはalwaysスマートポインタインスタンスを作成するために使用されます。いくつかの理由があります。
より短い-T
を繰り返す必要はありません(例:_std::unique_ptr<T>{new T}
_)、new
を使用する必要はありません。
より安全な例外。これらは、関数呼び出しでの評価の明確な順序の欠如によって引き起こされる潜在的なメモリリークを防ぎます。例えば。
_f(std::shared_ptr<int>(new int(42)), g())
_
次の順序で評価できます:
new int(42)
g()
g()
がスローすると、int
がリークします。
(実行時の速度に関して)より効率的です。これは_std::make_shared
_にのみ適用されます。_std::shared_ptr
_の代わりにこれを使用すると、実装はオブジェクトと制御ブロックの両方に対して単一の割り当てを実行できます。
詳細については この質問 を参照してください。
常にnew
を使用することをお勧めします。 malloc
を使用する場合でも、スペースが割り当てられているかどうかを手動で確認する必要があります。
最新のc ++では、スマートポインターを使用できます。 make_unique
およびmake_shared
new
を明示的に呼び出すことはありません。 std::unique_ptr
は基礎となるポインタより大きくなく、それを使用するオーバーヘッドは最小限です。
"new
またはmalloc
を使用する必要がありますか?に対する答えは単一の責任ルールです。
リソース管理は、それを唯一の目的とするタイプで行う必要があります。
これらのクラスはすでに存在します。たとえば、unique_ptr
、vector
などです。
malloc
またはnew
を直接使用することは、主要な罪です。
zwolの答え は正しい正解の答えを既に提供しています:Cインターフェースと相互作用するときはmalloc()
/free()
を使用してくださいonly。
これらの詳細を繰り返すつもりはありません。パフォーマンスの質問に答えます。
真実は、malloc()
とnew
のパフォーマンスは異なる可能性があり、実際には異なるということです。 new
を使用して割り当てを実行すると、メモリは通常、operator new()
とは異なるグローバルmalloc()
関数の呼び出しを介して割り当てられます。 operator new()
を呼び出してmalloc()
を実装するのは簡単ですが、これは必ずしも行われるとは限りません。
実際のところ、operator new()
を呼び出すmalloc()
がoperator new()
の標準実装よりも約100 CPUサイクル優れているシステムを見てきました。コールごと。これは確かに測定可能な違いであり、標準の実装がmalloc()
とは非常に異なる何かを行うことを明確に示しています。
したがって、パフォーマンスが心配な場合は、次の3つのことを行う必要があります。
パフォーマンスを測定します。
グローバルoperator new()
関数とそのフレンドの代替実装を記述します。
パフォーマンスを測定して比較します。
利益/損失は重要な場合とそうでない場合があります。