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 = ; class JustTesting
{
private:
string words;
int number;
public:
JustTesting(const string &s = "Just Testing", int n = )
{
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 memory
JustTesting *pc1, *pc2; pc1 = new (buffer)JustTesting; // place object in buffer
pc2 = new JustTesting("heap1", ); // 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", );
pc4 = new JustTesting("Heap2", ); cout << "Memory contents: \n";
cout << pc3 << ": ";
pc3->Show();
cout << pc4 << ": ";
pc4->Show(); delete pc2; // free heap1
delete pc4; // free heap2
delete [] buffer; // free buffer
cout << "Done\n"; return ;
}
执行结果:
[root@localhost 桌面]# ./new
Just Testing constructed
heap1 constructed
Memory block address:
buffer: 0x936a008 heap: 0x936a248
Memory contents:
0x936a008: Just Testing,
0x936a248: heap1,
bad Idea constructed
Heap2 constructed
Memory contents:
0x936a008: bad Idea,
0x936a290: Heap2,
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", );
其中指针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 memory
JustTesting *pc1, *pc2; pc1 = new (buffer) JustTesting; // place object in buffer
pc2 = new JustTesting("Heap1", ); // 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", );
pc4 = new JustTesting("Heap2", ); cout << "Memory contents: ";
cout << pc3 << ": ";
pc3->Show();
cout << pc4 << ": ";
pc4->Show(); delete pc2; // free heap1
delete pc4; // free heap2
// explicitly destroy placement new object
pc3->~JustTesting(); // destroy object pointed to by pc3
pc1->~JustTesting(); // destroy object pointed to by pc1
delete []buffer; // free buffer
cout << "Done/n"; return ;
}
placement new 操作符的更多相关文章
- C++中placement new操作符(经典)
placement new是重载operator new的一个标准.全局的版本,它不能被自定义的版本代替(不像普通的operator new和operator delete能够被替换成用户自定义的版本 ...
- 【转】c++中placement new操作符
new:指我们在C++里通常用到的运算符,比如A* a = new A; 对于new来说,有new和::new之分,前者位于std operator new():指对new的重载形式,它是一个函数, ...
- C++中placement new操作符
placement new是重载operator new的一个标准.全局的版本,它不能被自定义的版本代替(不像普通的operator new和operator delete能够被替换成用户自定义的版本 ...
- C++ 中 new 操作符内幕:new operator、operator new、placement new
一.new 操作符(new operator) 人们有时好像喜欢有益使C++语言的术语难以理解.比方说new操作符(new operator)和operator new的差别. 当你写这种代码: st ...
- c++ placement new概念
参考:http://www.cnblogs.com/Clingingboy/archive/2013/04/26/3044910.html 转:http://bbs.chinaunix.net/thr ...
- 标准模板库(STL)的一个 bug
今天敲代码的时候遇到 STL 的一个 bug,与 C++ 的类中的 const 成员变量有关.什么,明明提供了默认的构造函数和复制构造函数,竟然还要类提供赋值运算符重载.怎么会这样? 测试代码 Tes ...
- 【转载】C++内存分配
原文:C++内存分配 内存泄露相信对C++程序员来说都不陌生.解决内存泄露的方案多种多样,大部分方案以追踪检测为主,这种方法实现起来容易,使用方便,也比较安全. 首先我们要确定这个模块的主要功能: 能 ...
- 一个跨平台的 C++ 内存泄漏检测器
2004 年 3 月 01 日 内存泄漏对于C/C++程序员来说也可以算作是个永恒的话题了吧.在Windows下,MFC的一个很有用的功能就是能在程序运行结束时报告是否发生了内存泄漏.在Linux下, ...
- new的三种形态
C++语言一直被认为是复杂编程语言中的杰出代表之一,不仅仅是因为其繁缛的语法规则,还因为其晦涩的术语.下面要讲的就是你的老熟人—new: 它是一个内存管理的操作符,能够从堆中划分一块区域,自动调用构造 ...
随机推荐
- bzoj 1097 [POI2007]旅游景点atr(最短路,状压DP)
[题意] 给定一个n点m边的无向图,要求1开始n结束而且顺序经过k个点,给出经过关系x,y代表y必须在x之后经过,求最短路. [思路] 先对k个点进行spfa求出最短路. 设f[s][i]代表经过点集 ...
- Codeforces Round #365 (Div. 2) C - Chris and Road 二分找切点
// Codeforces Round #365 (Div. 2) // C - Chris and Road 二分找切点 // 题意:给你一个凸边行,凸边行有个初始的速度往左走,人有最大速度,可以停 ...
- HDU5479 Colmerauer 单调栈+暴力优化
http://acm.hdu.edu.cn/showproblem.php?pid=5749 思路: bestcoder 84 贡献:所有可能的子矩阵的面积和 //len1:子矩阵所有长的和 ;i&l ...
- jira部署,主机迁移,数据库迁移,jira
1,linux环境下快速部署; wget http://wpc.29c4.edgecastcdn.net/8029C4/downloads/software/jira/downloads/atlass ...
- [转载] I wish you enough
几天前,我在机场无意中听到一对父女告别时最后一刻的对白.广播员已经通知大家准备登机了.他们站在安检口旁边紧紧拥抱,父亲对女儿说:“我爱你,希望你一切都充足!” 女儿回答:“爸爸,我是那么满足我们在一起 ...
- red5下nginx安装配置
http://zfl110.iteye.com/blog/1155149 原址:http://lqw.iteye.com/blog/652763 安装Nginx 1.首先安装pcre-8.02.tar ...
- 搭建nodejs环境推荐用两个工具:nvm和npm
nvm 是 nodejs version manager 的简称,即:nodejs版本管理npm 是 nodejs package manager 的简称,即:nodejs模块管理 有了这两个工具,管 ...
- TMS320F2803x系列实时控制 MCU 技术文档
C2000系列实时控制器简介: C2000 生产选择指南 sprufk8.pdf 数据表: 中文板:TMS320F28030/28031/28032/28033/28034/28035 Picco ...
- CodeForces 707C Pythagorean Triples (数论)
题意:给定一个数n,问你其他两边,能够组成直角三角形. 析:这是一个数论题. 如果 n 是奇数,那么那两边就是 (n*n-1)/2 和 (n*n+1)/2. 如果 n 是偶数,那么那两边就是 (n/2 ...
- Webstorm2016激活码[ 转]
转至:http://blog.csdn.net/tingwode2014_/article/details/51063657 43B4A73YYJ-eyJsaWNlbnNlSWQiOiI0M0I0QT ...