operator new与placement new

article/2025/8/30 11:36:58

通常讲的new指的是new operator,使用new operator的时候,实际上执行了三个步骤:

1)调用operator new分配内存 ;2)调用构造函数生成类对象;3)返回相应指针。

分配内存这一操作是由operator new(size_t)来完成的,如果类重载了operator new,将调用foo::operator new(size_t ),否则调用全局::operator new(size_t ),后者由C++默认提供。

operator new  

operator new是函数,分为三种形式(前2种不调用构造函数,这点区别于new operator):  
void* operator new (std::size_t size) throw (std::bad_alloc);  
void* operator new (std::size_t size, const std::nothrow_t& nothrow_constant) throw();  
void* operator new (std::size_t size, void* ptr) throw();  
第一种分配size个字节的存储空间,并将对象类型进行内存对齐。如果成功,返回一个非空的指针指向首地址。失败抛出bad_alloc异常。  
第二种在分配失败时不抛出异常,它返回一个NULL指针。  
第三种是placement new版本,它本质上是对operator new的重载,定义于#include <new>中。它不分配内存,调用合适的构造函数在ptr所指的地方构造一个对象,之后返回实参指针ptr。  
第一、第二个版本可以被用户重载,定义自己的版本,第三种placement new不可重载。  
A* a = new A; //调用第一种  
A* a = new(std::nothrow) A; //调用第二种  
new (p)A(); //调用第三种  
new (p)A()调用placement new之后,还会在p上调用A::A(),这里的p可以是堆中动态分配的内存,也可以是栈中缓冲。   

重载operator new:

#include <iostream>
#include <string>
using namespace std;class X
{
public:X(){cout << "X's constructor" << endl;}~X(){cout << "X's destructor" << endl;}void* operator new(size_t size, string str){cout << "operator new size " << size << " with string " << str << endl;return ::operator new(size);//此处重载的是第几个operator new ? 调用了X()}void operator delete(void* pointer){cout << "operator delete" << endl;::operator delete(pointer);}
private:int num;
};int main()
{X* p = new("A new class") X;delete p;return 0;
}

 输出结果:

placement new就是在用户指定的内存位置上构建新的对象,这个构建过程不需要额外分配内存,只需要调用对象的构造函数即可。举例来说:
class foo{};
foo* pfoo = new foo;
pfoo指向的对象的地址是不能决定的,new做了这些工作。第一步分配内存,第二步调用类的构造函数。

placement new

placement new是怎么做的呢,把原本new做的两步工作分开来。第一步你自己分配内存,第二步你调用类的构造函数在自己分配的内存上构建新的对象。

placement new的优点:
1)在已分配好的内存上进行对象的构建,构建速度快。适合对时间要求比较高,长时间运行不希望被打断的应用程序。
2)已分配好的内存可以反复利用,有效的避免内存碎片问题。

placement new和其他普通的new不同的是,它在括号里多了另外一个参数。比如:

Widget * p = new Widget; //ordinary new  //普通的new pi = new (ptr) int;
pi = new (ptr) int; //placement new

括号里的参数是一个指针,它指向一个内存缓冲器,placement new将在这个缓冲器上分配一个对象。Placement new的返回值是这个被构造对象的地址(比如扣号中的传递参数)。placement new主要适用于:在对时间要求非常高的应用程序中,因为这些程序分配的时间是确定的;长时间运行而不被打断的程序;以及执行一个垃圾收集器(garbage collector)。

使用方法

在很多情况下,placement new的使用方法和其他普通的new有所不同。这里提供了它的使用步骤。

第一步  缓存提前分配

为了保证通过placement new使用的缓存区的memory alignmen(内存队列)正确准备,使用普通的new来分配它:

class Task ;

char * buff = new [sizeof(Task)]; //分配内存

(auto或者static内存并非都正确地为每一个对象类型排列,所以不能以placement new使用它们。)

第二步:对象的分配

在刚才已分配的缓存区调用placement new来构造一个对象。

Task *ptask = new(buff) Task

第三步:使用

按照普通方式使用分配的对象:

ptask->suspend();

ptask->resume();

//...

第四步:对象的析构

使用完这个对象必须调用它的析构函数来毁灭它。按照下面的方式调用析构函数:

ptask->~Task(); //调用外在的析构函数

第五步:内存释放

可以反复利用缓存并给它分配一个新的对象(重复步骤2,3,4)如果不打算再次使用这个缓存,可以象这样释放它:

delete [] buff;

跳过任何步骤就可能导致运行时间的崩溃,内存泄露,以及其它意想不到的情况。


http://chatgpt.dhexx.cn/article/6D3RtCpo.shtml

相关文章

ICC II 2 placement

整个笔记比较长 建议搜索食用 placement的关键步骤 #mermaid-svg-gdanrmmgqcQiRsLU .label{font-family:trebuchet ms, verdana, arial;font-family:var(--mermaid-font-family);fill:#333;color:#333}#mermaid-svg-gdanrmmgqcQiRsLU .label text{fill:#333}#mermaid-svg-gdanr…

openstack placement

openstack placement posted on 2018-07-18 14:06 秦瑞It行程实录 阅读( ...) 评论( ...) 编辑 收藏 转载于:https://www.cnblogs.com/ruiy/p/9328845.html

OpenStack部署之Placement项目(7-4)

OpenStack部署之Placement项目&#xff08;7-4&#xff09; 一、Placement概述二、OpenStack-Placement组件部署1、创建数据库实例和数据库用户2、创建Placement服务用户和API的endpoint3、安装placement服务4、修改00-placemenct-api.conf配置文件5、测试访问和端口号6、总结 …

Placement service – placement安装(wallaby-allinone)

Placement service – placement安装&#xff08;wallaby-allinone&#xff09; 1 必须 在安装和配置放置服务之前&#xff0c;您必须创建数据库、服务凭证和 API 端点。 创建数据库 要创建数据库&#xff0c;请完成以下步骤&#xff1a; 使用数据库访问客户端以root用户身份…

Placement Rules 使用文档

注意 本文介绍如何手动在 Placement Driver (PD) 中设置 Placement Rules。推荐使用 Placement Rules in SQL&#xff0c;让你更方便地设置表和分区的放置。 Placement Rules 是 PD 在 4.0 版本引入的一套副本规则系统&#xff0c;用于指导 PD 针对不同类型的数据生成对应的调…

Placement Driver

目录 PD架构 路由功能 TSO分配 时间窗口 调度 Label 例题 PD架构 PD由至少三个节点组成&#xff0c;并集成了ETCD&#xff0c;支持自动故障转移&#xff0c;无需担心单点故障 &#xff1b;同时ETCD raft 保证数据一致性 三个PD节点中有一个leader&#xff0c;当leader出…

Placement

程序功能&#xff1a;进入brd版图环境下的布局显示模式。 快捷键为&#xff1a;p或者P 布局模式&#xff0c;只显示器件的焊盘、器件外形丝印、ROUTE KEEPOUT铜皮、PACKAGE KEEPOUT铜皮和器件的PLACE_BOUND铜皮。

ICC图文流程——(三)布局Placement

ICC布局阶段 在布局规划阶段完成了芯片的整体规划&#xff0c;而布局阶段主要是软件自动的标准单元的摆放。 在布局开始之前&#xff0c;需要对设计进行确认和检查。 主要确认内容包括&#xff1a; 检查设计中的所有macro是否设置为dont_touch属性。在大多数情况下&#xff0…

想要彻底掌握placement各种技巧,这个一定可以如你所愿

想要彻底掌握placement各种技巧&#xff0c;这个一定可以如你所愿&#xff01; 文章右侧广告为官方硬广告&#xff0c;与吾爱IC社区无关&#xff0c;用户勿点。点击进去后出现任何损失与社区无关。 大家应该也都知道最近小编在忙项目&#xff0c;而且是相当的忙&#xff0c;到处…

openstack 【T版】(四)——部署placement

openstack 【T版】&#xff08;四&#xff09;——部署placement 一、Placement概念二、OpenStack-Placement组件部署1.创建数据库实例和数据库用户2.创建placement用户、授权、创建placement服务3.注册API端口到placement的service中&#xff1b;注册的信息会写入到mysql中4.安…

牛血清白蛋白标记微囊藻毒素(MCLR)(BSA-MCLR)

本制品以牛血清白蛋白BSA-微囊藻毒素MCLR经化学交联获得的偶联物。 微囊藻毒素(Microcystin&#xff0c;MC)是一类具有生物活性的环状七肽化合物 MC具有水溶性和耐热性&#xff0c;加热煮沸都不能将毒素破坏&#xff1b;自来水处理工艺的混凝沉淀、过滤、加氯、氧化、活性炭吸…

you-get使用二三谈 (亲测感想 )

1.you-get是什么 you-get是Github上的一个项目&#xff0c;源项目托管地址对其介绍如下&#xff1a;You-Get is a tiny command-line utility to download media contents (videos, audios, images) from the Web, in case there is no other handy way to do it. You-Get是一…

预训练语言模型论文分类整理

© 作者&#xff5c;王晓磊 机构&#xff5c;中国人民大学高瓴人工智能学院博士生 导师&#xff5c;赵鑫教授 研究方向 | 对话系统 1. 引言 近年来&#xff0c;以 BERT 和 GPT 系列为代表的大规模预训练语言模型&#xff08;Pre-trained Language Model, PLM&#…

Antigen for exchange 部署+评测

antigen系列是Forefront系列的早期版本&#xff0c;基本上除了换了个名字意外别的界面都没有换&#xff0c;微软的windows让我们家喻户晓&#xff0c;可是微软做杀毒软件却远不及诺顿等杀软大牌厂商&#xff0c;当微软推出Forefront的时候&#xff0c;又一次的给人以惊喜&#…

Windows10内置Linux子系统初体验

转载自&#xff1a; http://www.jianshu.com/p/bc38ed12da1d WSL 前言 前段时间&#xff0c;机子上的win10又偷偷摸摸升级到了一周年正式版&#xff0c;比较无奈。不过之前听闻这个版本已经支持内置的linux子系统&#xff0c;于是就怀着好奇心试玩了一把。虽然期间遇到了很多问…

《预训练周刊》第29期:Swin Transformer V2:扩大容量和分辨率、SimMIM:用于遮蔽图像建模的简单框架...

No.29 智源社区 预训练组 预 训 练 研究 观点 资源 活动 关于周刊 本期周刊&#xff0c;我们选择了10篇预训练相关的论文&#xff0c;涉及图像处理、图像屏蔽编码、推荐系统、语言模型解释、多模态表征、多语言建模、推理优化、细胞抗原预测、蛋白结构理解和化学反应的探索。此…

《预训练周刊》第51期:无重构预训练、零样本自动微调、一键调用OPT

No.51 智源社区 预训练组 预 训 练 研究 观点 资源 活动 周刊订阅 告诉大家一个好消息&#xff0c;《预训练周刊》已经开启“订阅功能”&#xff0c;以后我们会向您自动推送最新版的《预训练周刊》。订阅方法&#xff1a; 方式1&#xff1a;扫描下面二维码&#xff0c;进入《预…

Antigen for LCS2005

Antigen For LCS2005<?xml:namespace prefix o ns "urn:schemas-microsoft-com:office:office" /> Antigen for LCS2005是一款应用于即时通信内的杀毒&#xff0c;防毒软件。 试验拓扑图如下&#xff1a; Berlin是域LCS的域控制器也是DNS服务器&#xff0c;…

forefront for antigen

forefront for antigen antigen软件是保护企业Exchange 2003和Exchange 2000的。可以有效的防止病毒通过邮件的传输来危害计算机&#xff0c;而且antigen软件集合了八家杀毒公司的引擎&#xff0c;是让人心动的一面&#xff0c;如果能把杀毒的工作做好&#xff0c;那是很有潜力…

详解Microsoft Antigen for exchange9.0部署与测试

今天为大家介绍的是Microsoft Forefront系列的早期版本Antiget&#xff0c;Antigen for exchange9.0集成了九款杀毒引擎。微软的windows已经让我们家喻户晓了&#xff0c;当微软推出Forefront的时候&#xff0c;又一次的给人以惊喜&#xff0c;最具有竞争力的就是微软用自己雄厚…