31

C ++ Primer第4版、755ページによると、次のようなメモがあります。

最近のC++プログラムでは、通常、アロケータクラスを使用してメモリを割り当てる必要があります。より安全で柔軟性があります。

私はこの声明をよく理解していません。newこれまでのところ、私が読んだすべての資料は、C++でメモリを割り当てるために使用する方法を教えています。ベクトルクラスがアロケータをどのように利用するかの例は、本に示されています。しかし、他のシナリオは考えられません。

誰かがこの声明を明確にするのを手伝ってもらえますか?もっと例を教えてください。アロケータはいつ使用する必要がありますnewか?ありがとう!

4

2 に答える 2

48

一般的なプログラミングでは、はい、とを使用する必要がnewありdeleteます。

ただし、ライブラリを作成している場合は、作成しないでください。私はあなたの教科書を持っていませんが、それは図書館のコードを書くという文脈でアロケータについて議論していると思います。

ライブラリのユーザーは、何がどこから割り当てられるかを正確に制御したい場合があります。ライブラリのすべての割り当てが実行されnewdelete場合、ユーザーはそのきめ細かいレベルの制御を行う方法がありません。

すべてのSTLコンテナは、オプションのアロケータテンプレート引数を取ります。コンテナは、内部メモリのニーズに合わせてそのアロケータを使用します。デフォルトでは、アロケータを省略すると、 and (具体的には、 )std::allocatorを使用するアロケータが使用されます。newdelete::operator new(size_t)::operator delete(void*)

このようにして、そのコンテナのユーザーは、必要に応じてメモリがどこから割り当てられるかを制御できます。

STLで使用するためのカスタムアロケータの実装例と説明:STL用のカスタムプールアロケータによるパフォーマンスの向上

補足:アロケータへのSTLアプローチは、いくつかの点で最適ではありません。これらの問題のいくつかについては、「より良いアロケータモデルに向けて」を読むことをお勧めします。

2019年の編集:この回答が書かれてから、C++の状況は改善されました。ステートフルアロケータはC++11でサポートされており、そのサポートはC++17で改善されました。「より良いアロケータモデルに向けて」に関与した人々の何人かはそれらの変更に関与したので(例:N2387)、それは素晴らしいことです(:

于 2011-04-11T22:09:57.607 に答える
1

2つは矛盾していません。アロケータは、オブジェクトで使用するためにメモリのチャンクを割り当てるためにSTLライブラリのコンテナアダプタによって使用されるPolicyPatternまたはStrategyPatternです。

これらのアロケータは、要素の範囲を一度に割り当てることを許可し、ブロックサイズに応じてセカンダリの特殊なヒープから選択される配置の新しいアイテムを使用して初期化することにより、メモリ割り当てを頻繁に最適化します。

いずれにせよ、最終的な結果は(ほとんどの場合)オブジェクトが新しい(配置またはデフォルト)で割り当てられることです。


もう1つの鮮やかな例は、たとえばBoostライブラリがスマートポインターを実装する方法です。スマートポインターは非常に小さいため(オーバーヘッドがほとんどないため)、割り当てのオーバーヘッドが負担になる可能性があります。実装では、割り当てを行うための専用のアロケータを定義するのが理にかなっているため、smartpointersの効率的なstd :: set <>、std :: map <...、smartpointer>などがあります。

(これで、boostは仮想を回避することで、ほとんどのスマートポインターのストレージを実際に最適化することをほぼ確信しています。したがって、vftは、クラスをPOD構造にし、ストレージとしてrawポインターのみを使用します。例の一部は適用されません。 、他の種類のスマートポインターに外挿します(スマートポインターの再カウント、メンバー関数へのポインター、インスタンス参照を使用したメンバー関数へのポインターなど))

于 2011-04-11T22:08:24.847 に答える