《认清C++语言》---new and delete

C++核心语法与函数编程速查手册:从基础到现代特性实战指南 在C++编程中,掌握核心语法元素和函数机制是构建高效、安全软件的基础。理解变量、指针、引用等基本概念及其内存管理原理,是避免悬垂指针和内存泄漏等常见错误的关键。从函数声明、参数传递到返回值优化,这些技术直接影响代码的性能和可维护性。随着现代C++的发展,移动语义、lambda表达式和完美转发等特性极大地提升了代码的表达力和运行效率。本手册聚焦于C++基本语法和函数使用,通过直白的解释和代表性代码片段,为开发者提供一份即查即用的实战指南,帮助解决日常开发中关于constexpr、std::move等热词相关的 阅读详情

1)  new操作符(new operator)和operator new函数的区别:

 

下面的代码:

string *ps = new string("Memory Management");

使用的new是new操作符,这个操作符就像sizeof一样是内置于语言本身的。它所完成的功能分成两部分:首先分配足够的内存以便容纳所请求类型的对象(如上面的string对象);其次它会调用构造函数初始化刚刚分配的内存中的对象。new操作符总是做这两件事,我们不能以任何方式改变它的行为。

 

new操作符函数调用的那个用来完成必需的内存分配的函数就是operator new函数,我们可以重写或重载的就是这个函数。

函数operator new函数通常这样声明:

void *operator new(size_t size);

返回值的类型是void*,因为这个函数返回一个指针,这个指针指向原生的、未经初始化的一块内存;参数size指定要分配的内存的大小(字节为单位)。我们可以通过增加额外的参数重载operator new函数,但第一个参数的类型必须是size_t。

 

operator new函数的调用方式和普通函数一样:

void *rawMemory = operator new(sizeof(string));

就像malloc,operator new的唯一职责就是分配内存。把operator new函数返回的未经处理的指针转换成一个对象时new 操作符的工作,当编译器遇到下面的语句:

string *ps = new string("Memory Management");

它生成的代码与下面的相似:

void *memory = operator new(sizeof(string));

call string::string("Memory Management") on *memory;

string *ps = static_cast<string*>(memory);

上面第二步包含了构造函数的调用,程序员是不允许这样直接调用构造函数的,但编译器不受这个限制。

 

2) 有时我们确实想直接调用构造函数(尽管这是行不通的)。

在一个已存在的对象上调用构造函数是没有意义的,因为构造函数是用来初始化对象的,而一个对象只有在给它赋初值的时候初始化一次。

有时有些内存已经被分配但是尚未初始化,而我们需要在这块内存中构造一个对象,此时我们可以使用operator new函数的一个标准的重载版本:placement new函数。placement new允许我们在一个特定的位置“放置”对象,起到了调用一个构造函数的效果。

class ACEWidget

{

public :

         ACEWidget(int widgetSize);

         ....

};

ACEWidget *constructWidgetInBuffer(void *buffer, int widgetSize)

{

         return new (buffer) ACEWidget(widgetSize);

}

上面代码中的new操作符需要一个额外的变量buffer,当new操作符隐式调用operator new函数时,把这个变量传给它。被调用的operator new函数除了带有强制的参数size_t外,还必须接受void*指针参数,指向构造对象占用的内存空间,此时,这个operator new就是placement new:

void *operator new(size_t, void *location)

{

    return location;

}

在placement new的情况下,调用者很清楚指针location是什么类型的指针,因为他知道对象应该放在哪里。placement new必须做的就是返回传递给它的指针。size_t参数在这里没有用到,因为它是强制性的参数,所以没有名字,以防止编译器发出警告说它没有被使用。(也就是说,placement new的实现忽略了表示大小的实参,直接返回其第二个参数。)

placement new是标准C++库的一部分,为了使用placement new,需要包含#include <new>。

 

总结:如果想在堆上建立一个对象,那就使用new操作符,它既分配内存又为对象调用构造函数;如果仅仅想分配内存,那就调用operator new函数,它不会调用构造函数;如果想定制在堆对象被建立时的内存分配过程,就写一个自己的operator new函数,然后使用new操作符,new操作符会调用定制的operator new函数;如果想在一块已经有指针指向的内存里建立一个对象,就是用placement new。

 

注意:placement new函数不允许重写。

 

3) 函数operator delete和delete操作符的关系与operator new函数和new操作符的关系一样。

string *ps;

//.......

delete ps;

中的delete ps,编译器的理解差不多是:

ps->~string();

operator delete(ps);

 

因此,如果只想处理原始的、未被初始化的内存,可以调用operator new函数获得内存和operator delete函数释放内存:

void *buffer = operator new(10*sizeof(char));

//.........

operator delete(buffer);

而这与C中调用malloc和free等同。

 

如果使用placement new函数在内存中创建对象,应该避免针对这块内存使用delete操作符。因为delete操作符隐式调用operator delete函数来释放内存,但是包含对象的内存最初不是operator new函数分配的,placement只是返回传递给它的指针。此时应该显式调用对象的析构函数来销毁构造函数所建立的对象。

 

混淆电路:从百万富翁问题到隐私AI的安全多方计算实践 安全多方计算(MPC)是一种密码学技术,允许多个参与方在不泄露各自私有输入数据的前提下,共同计算一个函数并得到结果。其核心原理基于密码学协议,通过加密转换和分布式计算,确保数据在计算过程中始终保持隐私。这项技术的核心价值在于解决了数据孤岛与隐私保护之间的矛盾,使得跨机构的数据协作成为可能,而无需牺牲数据机密性。混淆电路作为MPC的一种代表性技术,通过将计算逻辑编译成加密的布尔电路,使参与方能够在不暴露输入的情况下执行计算,最终仅获得输出结果。它在联邦学习、医疗数据联合分析、金融风控等场景中发挥着关键作用,特 阅读详情

相关推荐

空间节省算法在Rowhammer防御中的应用与优化

空间节省算法(Space-Saving)是一种高效的流式数据处理算法,主要用于在有限内存条件下实时识别数据流中的高频项。其核心原理是通过维护固定大小的计数器表,动态跟踪最活跃的元素,适用于处理无限数据流场景。该算法在内存安全领域具有重要价值,特别是在Rowhammer攻击防御中,能够有效检测异常高频访问的DRAM行地址。通过结合计数器衰减策略(如DSAC)和混合架构设计,空间节省算法可以在保证低硬件开销的同时,提供高精度的攻击检测能力。这些技术已成功应用于现代DDR5内存控制器,展现出优异的工程实践价值。

weixin_31139479的博客 606

C++中的delete和delete[ ]的区别

以前看书的时候,书上说使用new申请的内存,释放时用delete,使用new [ ]申请的内存释放时要用delete [ ]才行,这两个一定要记住,申请时用了方括号,则释放时也要加上方括号,否则就会出错。但是并没有解释为什么这样,会出什么错。今天正好看到这个,记录下。关于动态申请的内存,分两种情况:基本数据类型的分配和自定义数据类型的分配。两者不同。1、基本数据类型 对于基本数据类型,假如有如下代...

Fearless的博客 7万+

全志T113 Tina5.0开发:(零)源码下载&修改调试串口

本文章主要作为自己的笔记,如有错误欢迎指出$ repo start product-da-t113-tina-stable --all # 全部下载完成之后,创建分支运行过程可能会出现版本问题;rm -rf .repo //先删除试试( 我安装的是3.6版本)

u014428915的博客 1164

C ++ delete 和delete[]

【原文引用如下】: C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。  关于 new[] 和 delete[],其中又分为两种情况:(1) 为基本数据类型分配和回收空间;(2) 为自定义类型分配和回收空间。  对于 (1),上面提供的程序a可以证明了 delete[] 和 de

WITNESS 1万+

【HarmonyOS】ArkUI的组件扩展

ArkuI的组件扩展主要是通过等装饰器来对于一些常用的自定义组件进行封装, 来简化UI开发流程, 提高自定义组件的可复用性。

2302_79763237的博客 1166

VOF模型求解方法:从SIMPLEC到PISO的稳定性优化策略

本文深入探讨了VOF模型求解方法中SIMPLEC与PISO算法的稳定性优化策略,重点分析了两种算法在稳态和瞬态问题中的应用差异。通过对比PRESTO离散化方法与其他格式的优劣,提供了针对多相流模拟的实用设置建议和稳定性优化技巧,帮助工程师有效提升计算效率和精度。

yellow的专栏 1153

C++ delete和delete[]区别

一般C++中delete和delete[]是跟new和new[]相对应的,即delete释放new分配的单个对象指针指向的内存,delete[]释放new分配的多个对象指针指向的内存,例如: int* a = new int; delete a; //delete释放单个对象指针a所指的内存 int* b = new int[10]; delete[] b; //delete释放多个对象指针b所指...

sanghyhgnas的博客 872

LabVIEW 调用MATLAB 进行图像处理的实现

程机械及设备的变形、振动、冲击、粗糙度、刚度和强度等特性,还可用在土木结构、水利设施的变形测量[4][5]。因此,该技术在机械、土木、水利、电器、航空航天、兵器工业及生物医学等领域的检测中具有非常重要的地位。将物面前方空间的散斑用摄像设备记录下来,当物体运动或由于受力而变形时,这些随机分布的散斑图也随之在空间按一定的规律运动,因此能用记录的散斑图在计算机上分析物体的运动和变形,这就是电子散斑技术。当物体的漫反射表面被激光照射时,漫反射的光波在物体表面的前方相互干涉,由于漫反射光的。

qq_37971227的博客 3873

c++详解【new和delete】

说起new和delete,了解过c++的人应该都知道吧,它是用来分配内存和释放内存的两个操作符。与c语言中的malloc和free类似。 c语言中使用malloc/calloc/realloc/free进行动态内存分配,malloc/calloc/realloc用来在堆上分配空间,free将申请的空间释放掉。 malloc: void FunTest() { int *pTest =

xxpresent的博客 2万+

Modbus 通信协议详解

Modbus是由 Modicon(现为施耐德电气公司的一个品牌)在 1979 年发明的,是全球第一个真正用于工业现场的总线协议。ModBus网络是一个工业通信系统,由带智能终端的可编程序控制器和计算机通过公用线路或局部专用线路连接而成。其系统结构既包括硬件、亦包括软件。它可应用于各种数据采集和过程监控。为更好地普及和推动Modbus在基于以太网上的分布式应用,目前施耐德公司已将Modbus协议的所有权移交给 IDA(,分布式自动化接口)组织,并成立了 Modbus-IDA 组织。

Projectsauron 的博客 7万+

下载igv报错:Error loading genome hg38raw.githubusercontent.com...如何解决?

🏆本文收录于 《全栈 Bug 调优(实战版)》 专栏。专栏聚焦真实项目中的各类疑难 Bug,从成因剖析 → 排查路径 → 解决方案 → 预防优化全链路拆解,形成一套可复用、可沉淀的实战知识体系。无论你是初入职场的开发者,还是负责复杂项目的资深工程师,都可以在这里构建一套属于自己的「问题诊断与性能调优」方法论,助你稳步进阶、放大技术价值 。

**My Coding Family** 988

C++中delete和delete[]的区别

一直对C++中的delete和delete[]的区别不甚了解,今天遇到了,上网查了一下,得出了结论。做个备份,以免丢失。 C++告诉我们在回收用 new 分配的单个对象的内存空间的时候用 delete,回收用 new[] 分配的一组对象的内存空间的时候用 delete[]。 关于 new[] 和 delete[],其中又分为两种情况:(1) 为基本数据类型分配和回收空间;(2) 为自定义类型分配和...

weixin_30512089的博客 166

100天精通Python(基础篇)——第1天:Python从起源到应用的全面解析(附上Python、PyCharm、VSCode下载安装详细教程)

100天精通Python(基础篇)——第1天:Python从起源到应用的全面解析(附上Python、PyCharm、VSCode下载安装详细教程)

努力让自己发光,对的人才能迎着光而来 101万+

C++ delete的三种面貌

一般来说,使用new申请空间时,是从系统的“堆”(heap)中分配空间。申请所得的空间的位置时根据当时的内存的实际使用情况决定的。但是,在某些特殊情况下,可能需要在程序员指定的特定内存创建对象,这就是所谓的“定位放置new”(placement new)操作。定位放置new操作的语法形式不同于普通的new操作。例如,一般都用如下语句A* p=new A;申请空间,而定位放置new操作则使用如下语句A

Doublelv 的博客专栏。 8769

WINCC7.3破解文件

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

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

《认清C++语言》---堆对象

强制在堆中建立对象:有时候,我们要求某种类型的对象能够自我销毁,也就是能够“delelte this”,因此,我们需要将此类型的对象分配在堆上。由于非堆对象在定义它的地方被自动构造,在生存期结束时被自动释放,因此我们只要禁止使用隐式的构造函数和析构函数就可以限制对象在堆上分配内存。 最直接的方法是将构造函数和析构函数都声明为private,但这样副作用太大。因此,最好将析构函数置为pr

ASCE1885 1739

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

《认清C++语言》之--内存管理

内存分配方式主要有三种:1)从静态存储区域分配;内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在,例如全局变量、static变量;2)在栈上创建;执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限;3)从堆上分配,即动态内存分配。使用malloc或new申

ASCE1885 1899

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

【一文读懂】《More Effective C++》35个改善程序与设计的有效方法

《More Effective C++》是 Meyers 继《Effective C++》后的进阶作品,35 个条款专注指针/多态、运算符重载、异常、效率、实现技巧,涉及智能指针、代理类、引用计数、表达式模板等高级技术。

码工许师傅 372

C++嵌入式开发:如何优化资源受限环境下的代码

本文围绕C++ 嵌入式开发在资源受限环境下的代码优化展开,针对 MCU 设备 Flash 小、RAM 有限、CPU 性能低等痛点,讲解实用优化方案。内容包括禁用异常与 RTTI、静态内存分配、内存池使用、栈空间管控等内存优化;通过编译器 - Os 选项、精简内联、轻量级库实现固件体积压缩;同时优化循环运算、编译期求值、硬件操作提升执行效率。文章强调可控、精简、确定的优化原则,帮助开发者在有限硬件下实现程序稳定、高效运行,适合嵌入式工程师参考。

不忘初心,方得始终。不管前路如何艰难,只要心中有梦想,就有力量。 224

深入解析C++/CLI托管模板:.NET泛型与原生C++的桥梁

泛型编程是现代软件开发中的核心概念,它通过参数化类型实现了代码的复用和类型安全。在.NET生态中,泛型是CLR(公共语言运行时)级别的支持机制,允许在运行时共享类型蓝图,同时保留丰富的类型信息。这一机制在混合编程场景中尤为重要,特别是当需要将高性能的原生C++代码与.NET框架集成时。C++/CLI托管模板正是为此而生,它在语法上借鉴了C++模板,但本质上生成的是.NET泛型类型,实现了托管堆上的参数化类型机制。通过托管模板,开发者可以构建高效的桥接层,将原生C++的计算核心安全地暴露给C#等托管语言调用,

weixin_33976072的博客 402

Qt嵌入式GUI开发实战:从信号槽机制到i.MX6平台部署全解析

在嵌入式系统开发中,图形用户界面(GUI)框架的选择直接影响开发效率和跨平台兼容性。信号与槽机制作为Qt框架的核心通信原理,通过类型安全的松耦合设计,实现了对象间的高效事件驱动通信,取代了传统的回调函数模式。这一机制不仅支持一对多、多对一的灵活连接,更内置了跨线程安全处理,为嵌入式多线程应用开发提供了坚实基础。其技术价值在于显著提升了代码的可维护性和模块复用性,尤其适用于工业控制、物联网设备等需要复杂交互的嵌入式场景。结合基于QObject的对象树内存管理模型,开发者能够有效避免内存泄漏,将精力集中于业务逻

weixin_30820077的博客 412
上一篇: 《认清C++语言》---堆对象
下一篇: 认清C++语言之《成员函数查找》
ACE1985
博客等级 码龄17年 1307粉丝 308原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值