std :: allocatorsがそれほど人気が​​ないのはなぜですか?[閉まっている]


8

CおよびC ++アプリケーションに関する最新の傾向、および最新とは最新の年を意味するため、がstd::allocator実際よりも頻繁に使用されることを期待していました。

現代のアプリケーションは通常、マルチスレッド化されているか、それらの形式で並行性があり、特にゲームやマルチメディアアプリケーションなどの一部の分野では、大量のメモリを管理します。そのため、通常の高額な割り当て/割り当て解除のコストが上昇し、古いアプリケーションよりもパフォーマンスに影響を与えます。

しかし、std::allocators によるこの種のメモリ管理は一般的ではないため、私が知っている1つのライブラリを数えることすらできません。つまり、標準化されたメモリ管理方法に関する理論的根拠を使用しています。

std::allocator人気がないのには本当の理由がありますか?技術的な理由?


2
使いにくいから?
ブライアンチェン

4
@BryanChenどういう意味ですか?アロケータは通常、標準コンテナの2番目の引数std::allocatorです。非常に使いやすいです。
user2485710

1
なぜstd::allocator(基本的にはラッパーnewと配置のラッパーであるnew)がそれほど使用されないのですか?または、なぜC ++の概念がAllocatorウィドリーを使用しないのかと尋ねていますか?これらは2つの異なる質問です。
デイブS

@DaveSは最初のオプションに似ていますが、なぜそれが2番目のオプションと異なるのか理解できません。コード自体の移植性に関連する何かを意味しますか?
user2485710

1
@BryanChen難しい理由を教えてくれませんか?落とし穴は何ですか?
user2485710

回答:


13

ここには2つの質問の種類があります。

1)これstd::allocator以上使用されないのはなぜですか?

短い答えは、使用して、理由はほとんどの用途のためであるnewdelete十分なものです。

最初に、C ++ 11アロケーターの概念の目的の概要。基本的に、を実行するとnew Foo、メモリが割り当てられ、そのメモリ内にオブジェクトが構築されます。

しかし、メモリを割り当てて2つの別個のステップとして構成する必要がある場合はどうでしょう。これの典型的な例はです。これはstd::vector、メモリをすぐに初期化せずにメモリを割り当てることができますが、コンテナーに追加するときに要素を構築します。のポイントは、std::allocatorこれらの個別のステップを統一的な方法で実行するためのインターフェースを提供することです。

ただし、例外をクリーンアップする際に覚えておかなければならないことの1つにすぎないため、ほとんどのユーザーにとって、そのレベルの制御は必要ありません。

2)C ++の概念を利用しないものが多いのはなぜAllocatorですか?

ほとんどの場合、必要はありません。それらを使用する傾向がある唯一のクラスは、ユーザーが割り当てるメモリのソースをユーザーがより細かく制御できるようにするクラスです。標準ライブラリコンテナーは、ユーザーが選択した場合にユーザーがこれらの決定を行うことができるように記述されていますが、デフォルトでは通常のアロケーターを使用します。


3
私の意見では本当の理由であるポイント1の+1。さまざまなメモリプールに多数のメモリアロケータを記述したことにはまったく同意できない「使いにくい」ではありません。アロケータは非常に簡単に記述でき、インターフェイスに準拠した一連のメソッドにすぎません。あなたは、メモリを簡単にすることができますか(合体メカニズムとチャンキング)難しいことができ、あなた次第です管理する方法
マルコA.

5

言語やライブラリのコンセプトの人気は、その根底にある複雑さと反比例しています。

std::allocator低レベルの概念であり、そのように潜在的な落とし穴があります。カスタムアロケーターを前もって持つことは、時期尚早の最適化と判断される可能性があります。さらに、他の低レベルの概念と同様に、独自の割り当ての複雑さを処理するオーバーヘッドが絶対的に正当化されない限り、ワーク割り当て管理をライブラリ(stdlib、boost)に委任することが一般的に推奨されます。

ポインターをこの論文のサポート例の1つと考えてください。私たちは、メモリへの自由なアクセスとオーバーヘッドなしのポインタを愛していますが、C ++では、スコープ/ raiiラッパーを使用して複雑さを管理する方がよいことを知っています。明確に定義されたユースケース。

std :: allocatorを使用する場合は、ABIとAPIの互換性、およびコードが
std::vector<T,A1>().swap(std::vector<T,A2>())さまざまな(そしてステートフルな!)アロケーターと関わっているときの望ましい動作などの素晴らしい質問を考慮する必要がA1ありA2ます。さらに、一部のコンテナは、意図したとおりにアロケータを使用していません。std::list<T,A>またはstd::map<K,T,C,A>を見てみましょう。当然のことながら、アロケータを使用しTてリストまたはpair<const K,T>マップにタイプのオブジェクトを割り当てることができますが、実際には、標準ライブラリの実装ではリストまたはマップノードを割り当てるように求められ、ノードのサイズもリリースビルドとデバッグビルドで異なります。カスタムアロケーターは細かいことが多く、追加された複雑さと詳細は、最も一般的なプログラミングタスクには不要です。


RAIIラッパーstd::unique_ptr<T>を使用してメモリを所有するのとは対照的に、オーバーヘッドは何T *ですか?
David Stone、

@DavidStone私はあなたがすでに知っていると推測しているように(トリックの質問をする)、答えはゼロです。
underscore_d

2

アロケータは、依存関係が注入されたポリシーであり、標準のコンテナに入れられます。すでに実装されているコンテナでは、クライアントコードが割り当てポリシーをインスタンス化から分離できるようにすることが主な目的です。

std ::コンテナを使用する必要があり、デフォルトの割り当てポリシー(std :: allocatorによって実装されている)がプロジェクトのニーズに合わない場合に問題が発生します(例:std :: vector実装でさらにスローする場合) 1024を超えるオブジェクトが割り当てられている場合、メモリプールを使用するか、割り当てがすべて特定のメモリ領域などに事前に割り当てられていることを確認します。

コンテナーに別のアロケーターを注入できなかった場合、一部のプロジェクトでstd :: containersを一緒に使用することが禁止されます。

これを回避するには(そして、複雑なメモリ要件がある場合でもstd ::コンテナーを使用できることを確認するには)、アロケーターはコンテナーのテンプレートパラメーターです。

あなたの質問に答えるには、ほとんどの人はstd :: allocatorsを使用しません。クライアントコードを作成するときに割り当てを完全に制御できるため、割り当てポリシーを挿入する必要がないためです。また、ライブラリコードを使用するときは、std ::アロケーターは通常十分です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.