placement new 操作符
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 操作符相关推荐
- C++中placement new操作符(经典)
placement new是重载operator new的一个标准.全局的版本,它不能被自定义的版本代替(不像普通的operator new和operator delete能够被替换成用户自定义的版本 ...
- placement new操作符
2019独角兽企业重金招聘Python工程师标准>>> acement new是operator new的一个重载版本,只是我们很少用到它.如果你想在已经分配的内存中创建一个对象,使 ...
- C++中的布局new操作符
C++中的布局new操作符 通常,new负责在堆内存中找到一个能够满足要求的内存块.new操作符还有一种变体:placement new 操作符,它能让你指定要使用的内存的位置. 程序员可以使用这种特 ...
- C++中nothrow的介绍及使用
在C中,使用malloc等分配内存的函数时,一定要检查其返回值是否为"空指针",并以此作为检查内存操作是否成功的依据,这种Test-for-NULL代码形式是一种良好的编程习惯,也 ...
- 一个跨平台的 C++ 内存泄漏检测器
From:http://www.ibm.com/developerworks/cn/linux/l-mleak2/index.html 内存泄漏对于C/C++程序员来说也可以算作是个永恒的话题了吧.在 ...
- 深入理解C++11 读书笔记(三) 通用与专用
继承构造函数 如果派生类并不需要改变构造函数,那么可以用新的using Base::Base直接继承基类的构造函数,基类构造函数很多的时候,这样做非常方便.如果派生类还有自己的成员需要初始化,可以利用 ...
- __mt_alloc源码分析(1)
本文从源代码级别研究mt allocator的内部实现,使用GCC 4.1.2版本的源码,主要源文件为库文件<ext/mt_allocator.h>和GCC源码中的"libstd ...
- C++ 中 new 操作符内幕:new operator、operator new、placement new
一.new 操作符(new operator) 人们有时好像喜欢有意使C++语言的术语难以理解.比方说new操作符(new operator)和operator new的差别. 当你写这种代码: st ...
- Placement new
new 操作一般可以分为两个过程:1为申请内存空间 2为调用类型的构造函数进行构造 placement new 调用类型的构造函数对已存在的内存进行构造 1 #include<new.h> ...
最新文章
- Nginx反向代理实现HTTPS网站
- 3说明书_电子产品说明书应该怎么翻译?知行君认为需要注意这3点
- 腾讯iOA零信任安全——IT变革下的新一代企业网
- WebUserControl归纳
- android取消自动调试模式吗,Android进入调试模式的三种技巧
- php 检测键名,【PHP教学|带你学习用PHP检测键名是否位于数组中,方法已经告诉你了,如果你想学就赶紧】- 环球网校...
- 7月5日服务器临时维护更新公告,封印战记7月5日更新什么? 7月5日临时更新维护公告...
- unity游戏开发毕设_基于unity游戏引擎的游戏设计毕设论文.doc
- 怎么把知网的外文文献翻译成中文_知网查重中文译成英文可行吗?
- 【转】Windows10彻底关闭休眠功能
- Python | Python保存高维数组array,Python用pandas将numpy保存csv文件,Python保存3维数组
- 爬取某视频网站电影,仅参考学习
- 申请工作居住证政策解答
- 【操作系统】“哲学家进餐”问题
- 微信小程序图片转换成文字_微信小程序中用canvas将文字转成图片,文字自动换行...
- python课程设计:公交线路查询系统
- MOOC浙大数据结构课后题记录——PTA数据结构题目集(全)
- 学术研究科研工具推荐,共9个,拿走不谢!
- Python Gdal 栅格数据处理之hgt转tif数据
- rocket mq 用户名密码访问
热门文章
- 计算机网络总结:第二章 应用层
- 在linux配置jdk教程,Linux中JDK安装配置教程
- python123期末测试第十周答案_Python语言设计_章节测验,期末考试,慕课答案查询公众号...
- 哈希是什么?为什么哈希存取比较快?
- Objective-C iOS纯代码布局 一堆代码可以放这里!
- 【分布式】Zookeeper请求处理
- JavaCodeTra 猴子选猴王 约瑟夫循环
- JPA Hibernate应用实例
- springMVC 前后台日期格式传值解决方式之一(共二) @DateTimeFormat的使用和配置...
- [0] 各类图形的数据大小获得