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;
}

另外,还有一个疑问需要澄清。上述做法是否良好(可能不是因为它可能会在更改循环条件时溢出容器)或放置新容器只能用于一次性分配变量。

如果我想一次性在单个容器中分配变量并检查边界泄漏,那么使用新位置分配变量的任何更好的方法。

4

3 回答 3

2

您自己已经回答了这个问题,基本上,当您想创建一个对象并告诉它它应该使用哪个内存地址时,将使用placement new。

Placement 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 的对象。

operator new(sizeof(T) * size)

然而,运算符 new 只分配内存,不需要 T 类型的默认构造。然后您可以使用placement new 在分配的内存中构造对象。这很有用,因为有许多类不提供默认构造,您无法在第一个示例中使用它们。

请注意,当使用placement new 时,您应该为要销毁的任何对象显式调用析构函数,而不是调用delete。此外,如果您使用 operator new 来分配内存,您应该使用 operator 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 回答