参考:
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相关推荐

  1. placement new和placement delete

    在第五版的<C++ primer>中,定位new(placement new)放在最后一章:特殊工具与技术中介绍,讲的比较简单.而在<effctive C++>中则用了一章的篇 ...

  2. 关于placement new 和 placement delete的重载,以及basic_string重载new()实例

    关于placement new 在https://blog.csdn.net/qq_42604176/article/details/111997397中已经介绍了placement new的形式. ...

  3. 关于C++的placement new和placement delete

    昨天发贴提了个问题,今天总结在这.原帖点击进入,有兴趣可以看看,我呆会儿还会说. C++的new是语言自定义的操作符,这个操作符的行为包含两件事,而且你不能改变. 第一件事:调用operator ne ...

  4. 写了placement new也要写placement delete——条款52

    placement new和placement delete并非C++兽栏中最常见的动物,如果你不熟悉它们,不要感到挫折或忧虑.回忆条款16和17,当你写一个new表达式像这样: Widget* pw ...

  5. C/C++编程:写了placement new也要写placement delete

    对于: Widget *pw = new Widget ; 共有两个函数被调用:一个是用以分配的operator new,一个是Widget的默认构造函数 假设第一个函数调用成功,第二个函数抛出异常- ...

  6. EffectiveC++-条款52:写了 placement new 也要写 placement delete

    一. 内容 placement new 和 placement delete 在 C++ 中并不常见,如果不熟悉它们,不要感到害怕和忧虑. 回忆条款16和17,当你写一个 new 表达式时: FStr ...

  7. placement new(转)

    今天看STL源码遇到一个问题: template <class _T1, class _T2> inline void _Construct(_T1* __p, const _T2& ...

  8. placement new--《C++必知必会》 条款35

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

  9. c++中的new、operator new、placement new

    一.定义 1.new new是c++中的关键字,,其行为总是一致的.它先调用operator new分配内存,然后调用构造函数初始化那段内存. new 操作符的执行过程: 1. 调用operator ...

最新文章

  1. python 图表_Python入门学习系列——使用Python调用Web API实现图表统计
  2. cf776G.Sherlock and the Encrypted Data
  3. 使用Reactor进行反应式编程最全教程
  4. MongoDB数据导入hbase + 代码
  5. Kyma Application connection url
  6. 如何撰写较受欢迎的技术文章
  7. CS144 lab0 笔记
  8. 04数据库的高级查询
  9. ios手机Safari本地服务连不上
  10. 红包 mysql表设计_微信红包的设计实现
  11. DIY个性家装心得家用电动工具选择
  12. 大数据项目实践 电影推荐系统概述(尚硅谷)
  13. MSTAR648方案遥控器配置
  14. 清理或破坏病毒流氓若干
  15. JAVA利用jsoup爬取百度热点信息
  16. 自学编程的好方法,直接省了几万块钱报班,不收藏就可惜了
  17. 数据通信之信道与编码
  18. 计算机专业必须做毕业设计吗,可以写和本专业无关的论文吗_计算机系的可以写别的系的论文吗_毕业论文一定要写和专业相关的吗...
  19. 李彦宏妻子马东敏向中科大捐赠一亿,成立“蔷薇科大发展基金”
  20. ZYNQ_使用PL-PS的中断

热门文章

  1. 我记得你往日的样子----聂鲁达
  2. 机器学习从入门到创业手记-1.4 难以理解的数学知识
  3. 人生25句最美丽的名句
  4. 格式化后如何恢复数据?
  5. 绿色石化高质量发展 茂名天源石化碳三碳四资源利用项目开工
  6. uniapp如何引入colorUI
  7. css分块代码,30 Seconds of CSS代码块解读(视觉篇)
  8. 2023年湖北省建筑类初级职称助理工程师电子版证书申报查询
  9. 什么是NFT?你不会还不知道吧!
  10. 解读:小比尔 · 福特认为特斯拉的成功并非因为马斯克