C++ 的placement new和placement delete
参考:
placement new和placement delete_hujing_Liu-CSDN博客
《effctive C++》p256
通常的C++程序中,new和delete表达式总是成对出现,并且分别调用了全局的operator new和operator delete,这两个全局操作符(或者直接理解为全局的函数)的基本形式如下:
void * operator new ( std::size_t) throw ( std::bad_alloc );void operator delete (void * rawMemory) throw();
现有一个class A,语句A *p = new A;
包含几步:
- 调用operator new分配内存,operator new (sizeof(A))
- 调用构造函数生成类对象,A::A()
- 返回相应指针
现在有一个微妙的问题:如果第一步的调用成功,分配了空间,但第二布的调用却抛出异常,那如何回收分配的内存空间呢?注意,这个时候这条语句是没有成功执行的,operator new
没能成功返回指向分配的内存空间的指针,也就是说p是无效的,所以程序员没有办法回收这块内存。
庆幸的是,C++编译器会自动地调用与operator new形式相对应的operator delete来回收那块空间。
placement new
如果operator new接受的参数除了一定会有的那个size_t之外还有其他参数,则称其为placement new。由这个定义可知我们可以重载出很多不同形式的placement new,其中一个特殊的是“接受一个指针指向对象该被构造之处”的placement new,这也是placement new名字的由来:特定位置上的new,定位new。其形式如下:
void * operator new ( std::size_t, void * ptr ) throw ( );
该版本的placement new已纳入C++标准库,通过#include来引入。其用途之一是负责在vector的未使用空间上创建对象(这点在STL中详细论述)。placement new的用法如下:
A *q = new ( ptr ) A; //ptr指向对象被构造之处
同样给出带指针的placement new对应的placement delete,形式如下:
void operator delete( void* pMemory, void *ptr ) throw() ;
需要注意的有两点:
1、如果程序员自定义了placement new,那么也应定义相应形式的placement delete,否则在调用该placement new构造对象并出现异常时,编译器找不到可用的placement delete来回收空间,这将导致内存泄露!
2、placement delete只有在“伴随placement new调用而触发的构造函数”出现异常时才会被调用。针对一个指针施行的delete绝不会导致调用placement delete。即使这个指针是由placement new返回的,也不会。例如对于上文的指针q,执行语句delete q时,调用的时全局的普通的operator delete,而不是带第二个参数的operator delete。
上面说到placement new的用途之一是在vector的未使用空间上创建对象。下面参考《STL源码剖析》给出部分解释:
在创建vector时,先调用空间配置器void *allocate(size_t n)来分配内存空间(《STL源码剖析》中说明了SGI STL的空间配置器分为两级,并给出了内部实现),再调用void construct(T1 *p, const T2& value)在分配的空间上构造对象。(construct函数包含在头文件<stl_construct.h>中,T1、T2是模板参数,详见《STL源码剖析》51页)
既然是在分配的空间上构造对象,显然要用到placement new,事实正是如此,construct函数内部就调用了placement new,源码如下:
template <class T1, class T2>
inline void construct(T1* p, const T2& value){new (p) T1(value);
}
vector的push_back函数内部则是调用construct来在末端加入新元素的。详见《STL源码剖析》122面。
C++ 的placement new和placement delete相关推荐
- placement new和placement delete
在第五版的<C++ primer>中,定位new(placement new)放在最后一章:特殊工具与技术中介绍,讲的比较简单.而在<effctive C++>中则用了一章的篇 ...
- 关于placement new 和 placement delete的重载,以及basic_string重载new()实例
关于placement new 在https://blog.csdn.net/qq_42604176/article/details/111997397中已经介绍了placement new的形式. ...
- 关于C++的placement new和placement delete
昨天发贴提了个问题,今天总结在这.原帖点击进入,有兴趣可以看看,我呆会儿还会说. C++的new是语言自定义的操作符,这个操作符的行为包含两件事,而且你不能改变. 第一件事:调用operator ne ...
- 写了placement new也要写placement delete——条款52
placement new和placement delete并非C++兽栏中最常见的动物,如果你不熟悉它们,不要感到挫折或忧虑.回忆条款16和17,当你写一个new表达式像这样: Widget* pw ...
- C/C++编程:写了placement new也要写placement delete
对于: Widget *pw = new Widget ; 共有两个函数被调用:一个是用以分配的operator new,一个是Widget的默认构造函数 假设第一个函数调用成功,第二个函数抛出异常- ...
- EffectiveC++-条款52:写了 placement new 也要写 placement delete
一. 内容 placement new 和 placement delete 在 C++ 中并不常见,如果不熟悉它们,不要感到害怕和忧虑. 回忆条款16和17,当你写一个 new 表达式时: FStr ...
- placement new(转)
今天看STL源码遇到一个问题: template <class _T1, class _T2> inline void _Construct(_T1* __p, const _T2& ...
- placement new--《C++必知必会》 条款35
placement new是重载operator new的一个标准.全局的版本,它不能被自定义的版本代替(不像普通的operator new和operator delete能够被替换成用户自定义的版本 ...
- c++中的new、operator new、placement new
一.定义 1.new new是c++中的关键字,,其行为总是一致的.它先调用operator new分配内存,然后调用构造函数初始化那段内存. new 操作符的执行过程: 1. 调用operator ...
最新文章
- python 图表_Python入门学习系列——使用Python调用Web API实现图表统计
- cf776G.Sherlock and the Encrypted Data
- 使用Reactor进行反应式编程最全教程
- MongoDB数据导入hbase + 代码
- Kyma Application connection url
- 如何撰写较受欢迎的技术文章
- CS144 lab0 笔记
- 04数据库的高级查询
- ios手机Safari本地服务连不上
- 红包 mysql表设计_微信红包的设计实现
- DIY个性家装心得家用电动工具选择
- 大数据项目实践 电影推荐系统概述(尚硅谷)
- MSTAR648方案遥控器配置
- 清理或破坏病毒流氓若干
- JAVA利用jsoup爬取百度热点信息
- 自学编程的好方法,直接省了几万块钱报班,不收藏就可惜了
- 数据通信之信道与编码
- 计算机专业必须做毕业设计吗,可以写和本专业无关的论文吗_计算机系的可以写别的系的论文吗_毕业论文一定要写和专业相关的吗...
- 李彦宏妻子马东敏向中科大捐赠一亿,成立“蔷薇科大发展基金”
- ZYNQ_使用PL-PS的中断