placement new, operator new and new operator

c++ 源码 之 标准库new , operator new , placement new , array new 在c++中管理内存的一些手段与细节 那么这篇博客的内容主要是在学习了jjhou老师的内存管理后我自己总结的一些知识点,关于侯捷老师的内存管理的内容可以自己搜索那么直接进入正题了 1.new和operator new 依照bjarne的c++ programming language的11.2.3章节所说,new ,delete,operator new,operator delete... 阅读详情

笔者觉得这3个new有点意思,有时候我也被搞懵了,这些创造者难不成觉得C++过于简单,所以搞一点含糊的术语出来。这次总结一下,以便再懵的时候有个参考。有错的地方请不吝赐教,多谢先!

简单点吧:

1. new operator,即熟悉的new操作符,用它从堆中分配一个对象,并且初始化。CHeapObject* p=new CHeapObject(name);

既然是操作符,那么它的行为就和其他+-*/操作符一样,是由C++语言定义的,不能改变,即使通过重载的方式也不能改变。C++规定了new操作符的行为:分配一个合适的空间容纳CHeapObject对象,然后调用其构造函数初始化对象。

2. operator new,就是new操作,1种说的“分配一个合适的空间容纳CHeapObject对象”就是通过new操作完成的。全局的new操作是如下声明的:

void * operator new(size_t size);

这是一个函数声明,在C++里我们可以通过重载该函数改变这个函数的行为,即分配空间的方式,相信大家都干过这事。

补充一下,虽然operator new是给new operator调用的,但是也可以被你调用,如:

void* p=operator new(sizeof(CHeapObject));

它只分配空间,等同于C里的malloc()。

虽然我们重载了operator new,但是我们没有改变1中new operator的行为。

3. placement new

唉,我又懵了:-)

这是在已经分配好的空间上(比如malloc, operatornew,返回的void*,没有对象信息),调用CHeapObject的对象构造函数,这也是一个特殊的new操作。上例子吧:

void* buffer=operator new(100*sizeof(CHeapObject));///分配100个对象的空间

CHeapObject* construct(void* buf, string objname)

{

  return new(buf) CHeapObject(objname);

}

这个函数返回对象指针,对象是在传递进来的buffer上分配。这个new的用法是new操作符的另一个用法,需要一个额外的变量buf,new操作的隐含调用operator new的时候会把buf传递给它,这是operator new的定义如下:

void * operator new(size_t, void *buffer)

{

  return buffer;

}

这就是placement new。


  当不再需要这个对象的时候,必须显式调用其析构函数释放空间。做这件事是有一些技巧的,因为许多人错误地假设对象会被自动销毁,错也!。在预分配的缓冲里构造另一个对象之前或者在释放缓冲之前,如果忘了显式调用析构函数,程序将产生不可预料的后果。

如果之前placement new了一个对象 Foo * pfoo = new (buff) Foo; //使用new操作在buff上构造一个 Foo

那么在用完之后应该显式的析构器声明:pfoo->~Foo(); //显式调用析构函数  

    换句话说,一个显式的析构器与普通的成员函数调用一样,只是名字与普通的成员函数稍有差别。一旦对象被销毁,便可以在预分配的内存中再次构造另一个对象。实际上,这个过程可以无限制地重复:构造一个对象,销毁它,然后又反复利用预分配的缓冲构造新对象。
    当不再需要预定义的缓冲时,或者说当应用程序关闭时,必须释放预定义的缓冲。使用delete完成这个任务。


最后来个总结吧:

如果想在堆上创建一个对象,应该用new操作符,它分配内存,同时又为对象调用构造函数。

如果仅仅想分配内存,就用operator new函数,它不会调用构造函数。

如果你想定制自己的在堆对象被建立时的内存分配过程,应该重载写你自己的operator new函数,new操作符会调用你定制的operator new。

如果想在一块已经分配好的内存里建立一个对象,使用placement new。


使用placement new的时候需要注意的几个问题

1)加上头文件#include <new>
2)你可以用placement new构造一个数组中的元素。
3)要析构一个用placement new分配的对象,你应该手工调用析构函数(并不存在一个“placement delete”)




转自 http://www.cnblogs.com/swpattern/archive/2010/05/11/1732352.html


用Omniverse Kit开发第一个USD插件:从环境配置到实战案例(Python 3.7版) 本文详细介绍了如何使用NVIDIA Omniverse Kit和Python 3.7开发第一个USD插件,涵盖从环境配置到实战案例的全过程。通过创建可实时同步材质属性的USD插件,开发者可以快速掌握Omniverse开发框架,提升3D内容创作效率。 阅读详情

相关推荐

海洋科学—物理海洋学 第五章 海洋环流

本章是基于《海洋科学导论》,但里面涉及到的重要的公式推导是专门拎出来推的,主要借鉴董昌明老师的《物理海洋学导论》,其中有一些多出来的推导,会在更新完整个物理海洋学之后重新拿出来一一讲解,最后开一个番外篇

qq_58518586的博客 1万+

从零实现C++ Vector:深入理解动态数组、内存管理与迭代器失效

动态数组是编程中管理连续内存的核心数据结构,其核心原理在于通过指针或索引追踪已用空间与总容量,实现高效的随机访问与动态扩容。在C++中,标准模板库(STL)的vector容器正是这一思想的经典实现,它通过精心设计的内存增长策略(如几何扩容)与异常安全保证,为开发者提供了强大且可靠的动态数组工具。理解其底层机制,尤其是内存的分配与释放、元素的构造与析构,以及迭代器失效的成因,对于编写高性能、健壮的C++代码至关重要。本文将以动手实现一个简化版vector为切入点,结合内存管理和移动语义等关键概念,深入解析动态

weixin_30899023的博客 277

实战避坑:示波器测量非隔离开关电源的炸机风险与隔离方案

本文详细分析了使用示波器测量非隔离开关电源时的炸机风险,揭示了地线环路导致的短路问题,并对比了四种防炸机解决方案,包括示波器隔离供电、拔掉电源地线、使用差分探头和被测板隔离供电。重点推荐使用隔离变压器方案,确保测量安全与精度,同时提供了实操建议与经验分享,帮助工程师避免常见测量事故。

weixin_29224309的博客 561

C++ New Operator and Placement New

Originally I was going to write this article to detail a particular problem I had recently with placement new in C++.  A page or two of writing later I decided it would be best to start with an introd

liziyun537的专栏 700

基于Xilinx Artix7 的FPGA高级应用 (二):千兆以太网通信(实战篇)第一期

本项目是基于Xlinx Artix7 XC7A35T芯片 以太网芯片选用的是RTL8211EG PHY芯片 MAC 和PHY接口标准是GMII 开发工具是vivado 2018.3 我们先来复习一下以太网的基本通信原理: 当我们的计算机需要与局域网中另外的设备进行通信的时候,需要将数据传输到网卡进行编码,然后传输到线上,经过另一个设备的网卡解码成该设备能读取的数据。 关于以太网协议的知识在原理篇中已经讲过,不再重复,下面直接看接收代码: 首先注意我们的MAC和PHY通信选择的是GMII接口标准,发送数据一

工大技术底层人员的博客 4034

CentOS 7 安装 Python 3.10

我这里已经软链接了,正常未链接之前是python->python2.7而不是python3.10。python2.7默认安装是在 /usr/bin目录中,切换到/usr/bin/更改yum配置,因为其要用到python2才能执行,否则会导致yum不能正常使用。2. 安装 Python 3.10 必需的 openssl >= 1.1.1。默认的centos7是没有安装pip,先添加epel扩展源。/usr/bin/python 修改为如下。添加软链接,将原来的链接备份。添加python3的软链接。

bensonyang888的博客 2905

placement new, operator new and new operator (转)

<br />笔者觉得这3个new有点意思,有时候我也被搞懵了,这些创造者难不成觉得C++过于简单,所以搞一点含糊的术语出来。这次总结一下,以便再懵的时候有个参考。有错的地方请不吝赐教,多谢先!<br />简单点吧:<br />1. new operator,即熟悉的new操作符,用它从堆中分配一个对象,并且初始化。CHeapObject* p=new CHeapObject(name);<br />既然是操作符,那么它的行为就和其他+-*/操作符一样,是由C++语言定义的,不能改变,即使通过重载的方式也不能

铁锤哥哥的专栏 719

诊断CAPL自动化(5) ——没有CANdela,无法编辑cdd数据库文件,也能轻松完成诊断测试

🍅我们知道cdd数据库文件,是CANoe测试环境的重要组件,它可以让我们更加轻松的完成诊断测试工作;但是创建和编辑cdd文件是需要CANdela 来完成的,一个 liscense 就要将近二十万,成本确实高🍅特别是在处理22/2E/31服务的时候,频繁的增加功能,可能需要频繁的用CANdela 修改CDD,我测试开发过程中,一般很少去修改cdd,有这个时间,纯手撸也开发完了,就一个CANdela,鬼知道此时此刻到了谁手里,我也懒得去找。🍅演示软硬件环境;目录📘前言。

蚂蚁小兵 5756

placement new, operator new and new operator (转)

笔者觉得这3个new有点意思,有时候我也被搞懵了,这些创造者难不成觉得C++过于简单,所以搞一点含糊的术语出来。这次总结一下,以便再懵的时候有个参考。有错的地方请不吝赐教,多谢先! 简单点吧: 1. new operator,即熟悉的new操作符,用它从堆中分配一个对象,并且初始化。CHeapObject* p=new CHeapObject(name); 既然是操作符,那么它的行为就和...

weixin_33863087的博客 80

低代码组件开发——OpenClaw智能助手的组件设计与开发(2026技术版)

OpenClaw智能助手的低代码组件开发平台采用分层架构设计,包含组件定义、注册、配置、渲染和生命周期管理等核心模块。该系统支持UI、功能、数据和集成四种组件类型,强调可重用性、可配置性和可扩展性。组件定义通过TypeScript、React等技术实现组件结构和行为的描述,组件注册中心基于Node.js和MongoDB管理组件版本。该平台通过React、Redux等技术实现组件渲染和状态管理,并提供完整的生命周期管理机制。这种架构设计显著提升了智能助手应用的开发效率和质量。

一键难忘的博客 407

基于 FPGA Vivado 示波器设计(附源工程)

今天给大侠带来基于 FPGA Vivado 示波器设计,开发板实现使用的是Digilent basys 3,如有想要入手basys3开发板的,可以联系牛总:18511371833。话不多说,上货。 本篇掌握基于添加文件和IP的Vivado工程设计流程,掌握基于Tcl的Vivado工程设计流程,学习示波器的基本组成结构。获取本篇相关源工程代码,可在公众号内回复“示波器设计源工程”。 原理介绍 数字存储示波器能够将模拟信号进行采样、存储以及显示。本系统在DIGILENT ...

7389

c++ - placement operator new() and the operator delete()

A class member operator new() can be overloaded. Provided that each delcaration has a unique paramter list. The first parameter of any class operator new() must always be a parameter of type size_t, f...

iteye_13882的博客 164

【ESP32CAM+Android+OpenCV】自定义目标数据集、训练自己的OpenCV模型部署到手机APP并对ESP32CAM无线图传显示并实时检测识别目标_资料编号30

本项目实现自定义目标数据集(想检测什么就检测什么,按照本文教程自己来更换目标)、训练自己的OpenCV模型实时检测识别(pycharm工程)。手机APP(Android studio工程)部署OpenCV模型实现对ESP32CAM(arduino工程)无线WIFI图传过来的图像实时检测识别。 本文以火焰检测识别为例进行演示,通过该过程,结合本文可自定义尝试更换为其它目标的检测,例如更换为车辆、车牌、手势、人脸面部活动、人脸表情、火焰烟雾、行人、口罩、行为、水果、植物、农作物、建筑、损伤等等部署进行检测。

嵌入式阿齐Archie 3482

new、operator new 、placement new

代码来自 www.cplusplus.com 直接上代码 #include <iostream> // std::cout #include <new> // ::operator new struct MyClass { int data[100]; MyClass() {std::cout << "constructe...

文王梦熊的博客 192

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

C++中的new、operator new与placement new

本文大部分内容转自http://www.cnblogs.com/luxiaoxun/archive/2012/08/10/2631812.html

loveRooney的专栏 694

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

我们无法重写[全局定位operator new],只能定义[类属定位operator new]

我们无法重写[全局定位operator new],只能定义[类属定位operator new]我们可以重写全局operator new,但是全局定位operator new除外,因为全局定位operator new的定义已经被内联到头文件(应该是头文件)中了,而其他全局operator new则仅仅是声名而已,以下是gcc编译环境中头文件中的部分内容:-------------------

874

VC中sqlite的使用

在VC中对sqlite的使用,实现数据库大批数据的快速插入,读取数据库中的数据在ListCtrl中显示

operator new与placement new

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

qq_44272681的博客 1160

C++ 中 new 操作符内幕:new operator、operator new、placement new

一、new 操作符(new operator) 人们有时好像喜欢故意使C++语言的术语难以理解。比如说new操作符(new operator)和operator new的区别。  当你写这样的代码: string *ps = new string("Memory Management");你使用的new是new操作符。这个操作符就象sizeof一样是语言内置的,你不能改变它的含义,它的功能总

buxizhizhou530的专栏 1476

C++ new 之 placement new、operator new、new operator

C++ new 之 placement new、operator new、new operator

u014023993的专栏 636

关于new operator, operator new, placement new

很久前就知道有这三个东西,除了第一个经常用,其他两个仅仅是知道有这个概念。        前几天在写一个内存池的例子,需要用到operator new 和 placement new,这才想着去翻书弄明白这两个概念。        new operator 就是我们平时的 new 一个对象。而这个new operator 包含两个操作:1.申请内存。2.在这个内存上调用构造函数,构造一个对象。

luotuo44的专栏 1307

关于C++的placement new和placement delete

昨天发贴提了个问题,今天总结在这。原帖点击进入,有兴趣可以看看,我呆会儿还会说。 C++的new是语言自定义的操作符,这个操作符的行为包含两件事,而且你不能改变。 第一件事:调用operator new分配内存。所以通常说的重载new函数其实重载的是operator new,你无法重载new。 第二件事:调用你要new的对象的所属类的构造函数初始化第一步中分配的内存。这就是为什么你Obj

程序猿 9813
上一篇: 从一道题谈C++中构造函数调用构造函数(像普通函数一样调用构造函数)
下一篇: GDB调试问题集
wind19
博客等级 码龄23年 477粉丝 170原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值