我正在为我的学习练习新课程。最初我认为放置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分配变量的任何更好的方法。
答案 0 :(得分: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];
答案 1 :(得分:1)
完整的放置点使其完全绕过C ++的内存管理。 A&#34;正常&#34; new将分配必要的内存,然后初始化它。 Placement new初始化您指定的地址,并假定可以覆盖该内存。你几乎不需要更换新品!
您可能希望使用替换new的典型方案是与不受应用程序控制的内存进行交互。这有时会发生在嵌入式系统或其他低级编程任务中。
答案 2 :(得分:1)
Placement new对于编写异常安全代码和减少对类型的要求也非常有用,因为您可以将内存分配与对象构造分开。
例如,
new T[size]
分配内存和默认构造类型为T的大小对象。
operator new(sizeof(T) * size)
然而,operator new只分配内存,不需要T类型的默认构造。然后可以使用placement new在该分配的内存中构造对象。这很有用,因为有许多类不提供默认构造,在第一个示例中无法使用。
请注意,在使用placement new时,您应该为要销毁的任何对象显式调用析构函数,而不是调用delete。此外,如果您使用operator new来分配内存,则应使用operator delete来释放它。 E.G。
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