2

私は自分の学習のために新しい配置を練習していました。最初は、placement new はメモリを自動的に管理し、変数が重複しないと思っていましたが、そうではないと思います (私を修正してこれを強調してください)。以下のコードは、同じアドレス位置に新しい変数を割り当てているようです。

int arr[2] = {};
cout<<arr<<endl;
for(int i = 0; i<2;i++)
{
    int *x = new(arr) int(i);
    cout<<*x<<" "<<x<<endl;
} 

以下のコードに修正すると問題が解決するようです(何か提案はありますか?それは正しいですか?)

int arr[2] = {};
cout<<arr<<endl;
for(int i = 0; i<2;i++)
{
    int *x = new(arr+i) int(i);
    cout<<*x<<" "<<x<<endl;
}

また、明確にする必要がある疑問があります。上記のプラクティスは適切ですか (ループ条件を変更するとコンテナーがオーバーフローする可能性があるためではない可能性があります)、または新しいコンテナーの配置は、一度に変数を割り当てるためにのみ使用する必要があります。

一度にではなく単一のコンテナーに変数を割り当て、境界リークもチェックする場合は、placement new を使用して変数を割り当てるより良い方法があります。

4

3 に答える 3

2

あなた自身が質問に答えました。基本的に、新しい配置は、オブジェクトを作成し、使用するメモリアドレスを指定するときに使用されます。

配置 new の一般的な使用法は、共有メモリにオブジェクトを作成することです

から: http://www.drdobbs.com/creating-stl-containers-in-shared-memory/184401639

共有メモリ内の C++ STL コンテナ マップ、ベクトル、リストなどの STL コンテナを共有メモリに配置することを想像してください。このような強力な汎用データ構造を共有メモリに配置することで、IPC に共有メモリを使用するプロセスに強力なツールが提供されます。共有メモリを介した通信のために特別なデータ構造を設計および開発する必要はありません。さらに、STL の柔軟性のすべてを IPC メカニズムとして使用できます。STL コンテナは内部で独自のメモリを管理します。アイテムが STL リストに挿入されると、リスト コンテナーは挿入されたアイテムを保持するための内部データ構造にメモリを自動的に割り当てます。STL コンテナを共有メモリに配置することを検討してください。コンテナ自体が内部データ構造を割り当てます。ヒープ上に STL コンテナを構築するのは不可能な作業です。

プロセス A は次のことを行います。

//Attach to shared memory
void* rp = (void*)shmat(shmId,NULL,0);
//Construct the vector in shared
//memory using placement new
vector<int>* vpInA = new(rp) vector<int>*;
//The vector is allocating internal data
//from the heap in process A's address
//space to hold the integer value
(*vpInA)[0] = 22;
Process B does the following:
vector<int>* vpInB =
  (vector<int>*) shmat(shmId,NULL,0);

//problem - the vector contains internal 
//pointers allocated in process A's address 
//space and are invalid here 
int i = *(vpInB)[0];
于 2013-07-23T06:34:40.930 に答える
1

配置 new は、オブジェクトの構築からメモリ割り当てを分離できるため、例外セーフなコードを記述し、型の要件を減らすのにも非常に役立ちます。

例えば、

new T[size]

メモリを割り当て、デフォルトでは T 型の size オブジェクトを構築します。

operator new(sizeof(T) * size)

ただし、演​​算子 new はメモリを割り当てるだけで、型 T のデフォルトの構築は必要ありません。その後、placement new を使用して、割り当てられたメモリ内にオブジェクトを構築できます。最初の例では使用できなかったデフォルトの構築を提供しない多くのクラスがあるため、これは便利です。

配置 new を使用する場合は、delete を呼び出す代わりに、破棄するオブジェクトのデストラクタを明示的に呼び出す必要があることに注意してください。また、演算子 new を使用してメモリを割り当てた場合は、演算子 delete を使用してメモリを解放する必要があります。例えば

auto pBlock = operator new(sizeof(T)); // allocate memory for T   
new (pBlock) T(value); // construct T in place
auto pT = static_cast<T*>(pBlock); // convert the pointer to something useful
pT->~T(); // destruct T
operator delete(pBlock); // free memory
于 2013-07-23T07:25:19.800 に答える
1

配置の全体的なポイントは、C++ のメモリ管理を完全に回避することです。「通常の」 new は、必要なメモリを割り当ててから初期化します。Placement new は、指定したアドレスを初期化し、そのメモリを上書きしてもよいと想定します。新品に交換する必要はほとんどありません!

置換 new を使用する典型的なシナリオは、アプリケーションの制御下にないメモリと対話することです。これは、組み込みシステムやその他の低レベルのプログラミング タスクで発生することがあります。

于 2013-07-23T06:33:05.747 に答える