1

コンテナがある場合:

std::vector<T*> elements;

オブジェクトがすべて連続して割り当てられるように、placement new を使用してオブジェクトを割り当てることはできますか? 私はこのようなことができるように:

size_t elementIndex = someRandomElement - elements[0];

どこsomeRandomeElementからのランダムな要素でelementsありelementIndex、正しいインデックスを格納するsomeRandomElementので、elements[elementIndex] == someRandomElement

これは、メモリ マネージャーの現在の実装に必要です。今日完成できた実装がありますが、要素 (ボクセル、三角形など) が GetIndex() および SetIndex() 関数を持つ必要があるため、要素がポインターとして返される場合、配列内の要素のインデックスを見つけることができますelements。つまり、変更できない要素(Ogre::Vector3としましょう)はマネージャーを使用できません(私の場合、断片化しているため、マネージャーを使用する必要があります想い出)。

私の唯一の他の解決策は、アクセサーとして機能し、インデックスと要素へのポインターを持つ構造を持つことですが、これによりメモリ使用量が増加します (現在 500 万の要素を扱っていることを考慮して)。

注: 今日投稿した同様の質問がありますが、そこにある回答は、私の要件に完全に反するいくつかの仮定を行っています。要件の 1 つは、ベクトルをポインターで満たす必要があることTです。そうしないと、コードベースの大部分を変更する必要があります。次に、100,000 (概算) を超える要素を初期化すると、bad_alloc 例外が発生します。各要素のサイズは 196 バイトです (132 バイトに減らすことができました)。

4

2 に答える 2

2

指し示すオブジェクトを連続させるには、2 つの適切なオプションがあります。

  • すべてを保持するのに十分な大きさの要素の単一配列を作成するために使用new[]し、それらに新しい値を割り当て、それらのアドレスを要素に入れます
  • malloc() を使用して、それらすべてを保持するのに十分な大きさの初期化されていないメモリ領域を作成します (十分に厳密に整列されている可能性がありますが、問題に注意する必要があります)。次に配置を使用newして、そのメモリ内に要素を構築します。

new[]配置newnew がメモリを上書きする前にデフォルトで構築された要素が破棄されないため、使用しないでください。

大きな配列を割り当てるのに十分なメモリがない場合、明らかにそれを行うことはできません...それは簡単です。100,000 個の個別new Tの s は、単一の s よりも多くのメモリを必要とすることが予想されnew T[100000]ます...割り当てに関連するパディングとヒープ管理のオーバーヘッドがあります。

于 2011-04-22T03:10:12.590 に答える
1

std::bad_alloc大きすぎる連続したメモリ ブロックを割り当てようとしているために、例外が発生する可能性があります。std::deque<T>そのため、代わりに a を使用することを検討してください。

std::vector<T*>何らかの理由でが引き続き必要であると判断した場合は、要素へのポインタを に格納できますstd::deque<T>。シーケンスの最初または最後に要素を追加および削除するだけである限り、ポインターが無効になることを心配する必要はありません。

于 2011-04-22T03:15:38.893 に答える