首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用placement new处理内存

使用placement new处理内存
EN

Stack Overflow用户
提问于 2013-07-23 14:27:07
回答 3查看 556关注 0票数 2

为了我的学习,我在练习新的安置。最初,我认为placement new将自动管理内存,并且不会使变量重叠,但我认为情况并非如此(请纠正我并强调这一点)。下面的代码似乎在相同的地址位置分配新的变量。

代码语言:javascript
复制
int arr[2] = {};
cout<<arr<<endl;
for(int i = 0; i<2;i++)
{
    int *x = new(arr) int(i);
    cout<<*x<<" "<<x<<endl;
} 

将其更正为下面的代码似乎可以解决问题(有什么建议吗?它是否正确?)

代码语言:javascript
复制
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来分配变量有什么更好的方法。

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2013-07-23 15:25:20

Placement new对于编写异常安全代码和减少对类型的要求也非常有用,因为您可以将内存分配与对象构造分开。

例如,

代码语言:javascript
复制
new T[size]

分配内存和默认构造大小为T类型的对象。

代码语言:javascript
复制
operator new(sizeof(T) * size)

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

请注意,在使用placement new时,您应该显式调用要销毁的任何对象的析构函数,而不是调用delete。此外,如果您使用操作符new来分配内存,则应该使用操作符delete来释放它。例如。

代码语言:javascript
复制
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
票数 1
EN

Stack Overflow用户

发布于 2013-07-23 14:34:41

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

放置new的典型用法是在共享内存上创建一个对象。

来自:http://www.drdobbs.com/creating-stl-containers-in-shared-memory/184401639

共享内存中的STL容器想象一下在共享内存中放置C++容器,如映射、向量、列表等。将这种强大的通用数据结构放在共享内存中,为IPC使用共享内存的进程配备了一个强大的工具。不需要设计和开发特殊的数据结构来通过共享内存进行通信。此外,STL的全部灵活性都可以用作IPC机制。STL容器在幕后管理自己的内存。将项插入到STL列表中时,列表容器会自动为内部数据结构分配内存,以容纳插入的项。考虑在共享内存中放置一个STL容器。容器本身分配其内部数据结构。在堆上构造STL容器,将容器复制到共享内存中,并确保所有容器的内部内存都指向共享内存区,这是一项不可能完成的任务。

进程A执行以下操作:

代码语言:javascript
复制
//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];
票数 2
EN

Stack Overflow用户

发布于 2013-07-23 14:33:06

整个布局的要点是完全绕过C++的内存管理。一个“普通的”new会分配必要的内存,然后初始化它。placement new初始化你指定的地址,并假定它可以覆盖那个内存。你几乎永远不需要替换new!

您可能希望使用替换new的典型情况是与应用程序无法控制的内存进行交互。这有时会发生在嵌入式系统或其他低级编程任务中。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17802891

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档