placement new操作符能够在分配内存时指定内存位置。下面的程序使用了placement new操作符和常规new操作符给对象分配内存。

// placenew.cpp -- new, placement new, no delete
#include <iostream>
#include <string>
#include <new>using namespace std;
const int BUF = 512;class JustTesting
{
private:string words;int number;
public:JustTesting(const string &s = "Just Testing", int n = 0){words = s; number = n; cout << words << " constructed\n";}~JustTesting() { cout << words << " destroyed\n"; }void Show() const { cout << words << ", " << number << endl; }
};int main(void)
{char *buffer = new char [BUF];    // get a block of memoryJustTesting *pc1, *pc2;pc1 = new (buffer)JustTesting;    // place object in bufferpc2 = new JustTesting("heap1", 20);    // place object on heap
cout << "Memory block address:\n" << "buffer: "<< (void *)buffer << "    heap: " << pc2 << endl;cout << "Memory contents: \n";cout << pc1 << ": ";pc1->Show();cout << pc2 << ": ";pc2->Show();JustTesting *pc3, *pc4;pc3 = new (buffer) JustTesting("bad Idea", 6);pc4 = new JustTesting("Heap2", 10);cout << "Memory contents: \n";cout << pc3 << ": ";pc3->Show();cout << pc4 << ": ";pc4->Show();delete pc2;    // free heap1delete pc4;    // free heap2delete [] buffer;    // free buffercout << "Done\n";return 0;
}

执行结果:

[root@localhost 桌面]# ./new
Just Testing constructed
heap1 constructed
Memory block address:
buffer: 0x936a008    heap: 0x936a248
Memory contents:
0x936a008: Just Testing, 0
0x936a248: heap1, 20
bad Idea constructed
Heap2 constructed
Memory contents:
0x936a008: bad Idea, 6
0x936a290: Heap2, 10
heap1 destroyed
Heap2 destroyed
Done

上面的程序使用placement new操作时存在两个问题。首先,在创建第二个对象时,placement new操作符使用一个新对象来覆盖用于第一个对象的内存单元。显然,如果类动态地为其成员分配内存,这将引发问题。

其次,将delete用于pc2和pc4时,将自动调用为pc2和pc4指向的对象调用析构函数;然而,将delete[]用于buffer时,不会为使用布局new操作符创建的对象调用析构函数。

为确定两个单元不重叠,可以这样做:

pc1 = new (buffer) JustTesting;
pc3 = new (buffer + sizeof(JustTesting)) JustTesting("Better Idea", 6);

其中指针pc3相对于pc1的偏移量为JustTesting对象的大小

第二个教训是,如果使用placement new操作符来为对象分配内存,必须确保其析构函数被调用,但如何确保呢?

例如,在堆中创建的对象,可以这样做:

delete pc2;

然而,对于使用placement new操作符创建的对象,不能像下面一样调用delete

delete pc1; // NO!!!

原因在于delete可与常规new操作符配合使用,但不能与placement new操作符配合使用。

那么我们要显示调用析构函数,必须指定要销毁的对象:

pc3->~JustTesting();   // destroy object pointed to by pc3

int main(void)
{char *buffer = new char[BUF];    // get a block of memoryJustTesting *pc1, *pc2;pc1 = new (buffer) JustTesting;    // place object in bufferpc2 = new JustTesting("Heap1", 20);    // place object on heap
cout << "Memory block addresses: /n" << "buffer: "<< (void *)buffer << "    heap: " << pc2 << endl;cout << "Memory contents: ";cout << pc1 << ": ";pc1->Show();cout << pc2 << ": ";pc2->Show();JustTesting *pc3, *pc4;// fix placement new location pc3 = new (buffer + sizeof(JustTesting)) JustTesting("better Idea", 6);pc4 = new JustTesting("Heap2", 10);cout << "Memory contents: ";cout << pc3 << ": ";pc3->Show();cout << pc4 << ": ";pc4->Show();delete pc2;        // free heap1delete pc4;        // free heap2// explicitly destroy placement new object
    pc3->~JustTesting();    // destroy object pointed to by pc3pc1->~JustTesting();    // destroy object pointed to by pc1delete []buffer;    // free buffercout << "Done/n";return 0;
}

placement new 操作符相关推荐

  1. C++中placement new操作符(经典)

    placement new是重载operator new的一个标准.全局的版本,它不能被自定义的版本代替(不像普通的operator new和operator delete能够被替换成用户自定义的版本 ...

  2. placement new操作符

    2019独角兽企业重金招聘Python工程师标准>>> acement new是operator new的一个重载版本,只是我们很少用到它.如果你想在已经分配的内存中创建一个对象,使 ...

  3. C++中的布局new操作符

    C++中的布局new操作符 通常,new负责在堆内存中找到一个能够满足要求的内存块.new操作符还有一种变体:placement new 操作符,它能让你指定要使用的内存的位置. 程序员可以使用这种特 ...

  4. C++中nothrow的介绍及使用

    在C中,使用malloc等分配内存的函数时,一定要检查其返回值是否为"空指针",并以此作为检查内存操作是否成功的依据,这种Test-for-NULL代码形式是一种良好的编程习惯,也 ...

  5. 一个跨平台的 C++ 内存泄漏检测器

    From:http://www.ibm.com/developerworks/cn/linux/l-mleak2/index.html 内存泄漏对于C/C++程序员来说也可以算作是个永恒的话题了吧.在 ...

  6. 深入理解C++11 读书笔记(三) 通用与专用

    继承构造函数 如果派生类并不需要改变构造函数,那么可以用新的using Base::Base直接继承基类的构造函数,基类构造函数很多的时候,这样做非常方便.如果派生类还有自己的成员需要初始化,可以利用 ...

  7. __mt_alloc源码分析(1)

    本文从源代码级别研究mt allocator的内部实现,使用GCC 4.1.2版本的源码,主要源文件为库文件<ext/mt_allocator.h>和GCC源码中的"libstd ...

  8. C++ 中 new 操作符内幕:new operator、operator new、placement new

    一.new 操作符(new operator) 人们有时好像喜欢有意使C++语言的术语难以理解.比方说new操作符(new operator)和operator new的差别. 当你写这种代码: st ...

  9. Placement new

    new 操作一般可以分为两个过程:1为申请内存空间 2为调用类型的构造函数进行构造 placement new 调用类型的构造函数对已存在的内存进行构造 1 #include<new.h> ...

最新文章

  1. Nginx反向代理实现HTTPS网站
  2. 3说明书_电子产品说明书应该怎么翻译?知行君认为需要注意这3点
  3. 腾讯iOA零信任安全——IT变革下的新一代企业网
  4. WebUserControl归纳
  5. android取消自动调试模式吗,Android进入调试模式的三种技巧
  6. php 检测键名,【PHP教学|带你学习用PHP检测键名是否位于数组中,方法已经告诉你了,如果你想学就赶紧】- 环球网校...
  7. 7月5日服务器临时维护更新公告,封印战记7月5日更新什么? 7月5日临时更新维护公告...
  8. unity游戏开发毕设_基于unity游戏引擎的游戏设计毕设论文.doc
  9. 怎么把知网的外文文献翻译成中文_知网查重中文译成英文可行吗?
  10. 【转】Windows10彻底关闭休眠功能
  11. Python | Python保存高维数组array,Python用pandas将numpy保存csv文件,Python保存3维数组
  12. 爬取某视频网站电影,仅参考学习
  13. 申请工作居住证政策解答
  14. 【操作系统】“哲学家进餐”问题
  15. 微信小程序图片转换成文字_微信小程序中用canvas将文字转成图片,文字自动换行...
  16. python课程设计:公交线路查询系统
  17. MOOC浙大数据结构课后题记录——PTA数据结构题目集(全)
  18. 学术研究科研工具推荐,共9个,拿走不谢!
  19. Python Gdal 栅格数据处理之hgt转tif数据
  20. rocket mq 用户名密码访问

热门文章

  1. 计算机网络总结:第二章 应用层
  2. 在linux配置jdk教程,Linux中JDK安装配置教程
  3. python123期末测试第十周答案_Python语言设计_章节测验,期末考试,慕课答案查询公众号...
  4. 哈希是什么?为什么哈希存取比较快?
  5. Objective-C iOS纯代码布局 一堆代码可以放这里!
  6. 【分布式】Zookeeper请求处理
  7. JavaCodeTra 猴子选猴王 约瑟夫循环
  8. JPA Hibernate应用实例
  9. springMVC 前后台日期格式传值解决方式之一(共二) @DateTimeFormat的使用和配置...
  10. [0] 各类图形的数据大小获得