【C++】内存管理(二):operator new/delete

news2024/11/25 15:29:09

大家好,我是苏貝,本篇博客带大家了解C++的operator new/delete,如果你觉得我写的还不错的话,可以给我一个赞👍吗,感谢❤️
在这里插入图片描述


目录

  • 1 new/delete的底层
  • 2 new/delete的底层调用顺序
  • 3 delete[ ]调用析构函数的次数
    • (A) 方法1
    • (B) 方法2
  • 4 new/new 类型[ ]必须和delete/delete[ ]匹配

注意:operator new/delete了解就可以

new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数(不是对new和delete的运算符重载),new在底层调用operator new全局函数来申请空间,delete在底层通过 operator delete全局函数来释放空间。
在这里插入图片描述

在这里插入图片描述

通过上述两个全局函数的实现知道,operator new 实际也是通过malloc来申请空间,如果 malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。

1 new/delete的底层

operator new是对malloc的封装,operator delete是对free的封装。

如果想使用operator new,那么必须将它写完整,不能简写成new
在这里插入图片描述

运算符在编译后就没有了,编译后的指令里没有运算符。所以new/delete在编译后就没有了,变成了下图所示的。new的底层是operator new,operator new的底层是malloc。delete的底层是operator delete,operator delete的底层是free

在这里插入图片描述
在这里插入图片描述

题外话:问,sizeof和strlen都是在什么时候得出结果的?
sizeof:运算符,在编译时就根据内置类型大小的定义或自定义类型根据结构体对齐规则计算出了结果
strlen:函数,在程序运行时才得出结果

2 new/delete的底层调用顺序

new毫无疑问是先operator new(先动态开辟空间)再调用构造函数,那么delete是先operator delete还是先调用析构函数呢?

在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

因此,delete是先调用析构函数,再operator delete

在这里插入图片描述

3 delete[ ]调用析构函数的次数

问:下图中delete[ ] p2;语句会调用几次析构函数?
在这里插入图片描述

10次,即new的对象的个数。

为什么编译器知道是new的对象个数10?
因为如果new的类型是自定义类型,且个数>1,且编译器会调用析构函数,那么编译器会在动态开辟的空间前再开辟4个字节的空间去存储new自定义类型的个数。这个4字节的空间就是在delete[ ]时,让编译器知道要调用多少次析构函数。
在这里插入图片描述

注意:即使会在动态开辟的空间前再开辟4个字节的空间去存储new自定义类型的个数,但是p2指向的还是b而非a

下面来证明

(A) 方法1

进入调试,显示出内存

在这里插入图片描述

在搜索框中输入p2后按回车键,就会显现出p2指向的空间的值。往上翻即可看见p2指向的空间前4个字节的空间的值是0a(十六进制)即10。成功证明

在这里插入图片描述

将new的对象改为5个,看看是否还是在开辟的空间前开辟了一个4字节的空间存储对象个数5。
在这里插入图片描述

事实确实如此

如果我们没有显示定义析构函数,那么编译器会自动生成一个析构函数。
问:如果编译器认为类A不需要在生命周期结束时调用析构函数,那么还会不会在开辟的空间前开辟一个4字节的空间存储对象个数?

(下图较之前只是删除了析构函数。如果我们显示定义了析构函数,那么编译器在对象生命周期结束后一定会调用析构函数)

在这里插入图片描述
在这里插入图片描述

答案是不会。如果编译器认为类A不需要在生命周期结束时调用析构函数,那么就不会在开辟的空间前开辟一个4字节的空间存储对象个数

如果new的是内置类型,那么会不会在开辟的空间前开辟一个4字节的空间存储对象个数?
不会,因为内置类型没有析构函数,所以不会

(B) 方法2

在这里插入图片描述

看push后面的数据14(十六进制)即16+4=20字节。sizeof(A)==4,4*5=20,所以就不会在开辟的空间前开辟一个4字节的空间存储对象个数

在这里插入图片描述

再看一个会在开辟的空间前开辟一个4字节的空间存储对象个数的例子:在类A中显示写析构函数
在这里插入图片描述
在这里插入图片描述

看push后面的数据18(十六进制)即16+8=24字节。sizeof(A)==4,4*5=20,所以会在开辟的空间前开辟一个4字节的空间存储对象个数

4 new/new 类型[ ]必须和delete/delete[ ]匹配

如果不匹配使用,如new 类型[ ]却用delete来释放空间,会报错
在这里插入图片描述
在这里插入图片描述

为什么?
在这里插入图片描述

因为如果new的是自定义类型,且new的对象>1,且编译器会调用析构函数,那么会在开辟的空间前开辟一个4字节的空间存储对象个数。
现在delete p,即从p的位置开始释放,那么就落下了存储对象个数的空间,释放开辟的空间能从之间释放吗?不能,只能从最开始即a点释放,所以报错

因此,如果new的是自定义类型,且new的对象>1,但编译器不会调用析构函数,那么就不会报错,因为不会在开辟的空间前开辟一个4字节的空间存储对象个数。

在这里插入图片描述


好了,那么本篇博客就到此结束了,如果你觉得本篇博客对你有些帮助,可以给个大大的赞👍吗,感谢看到这里,我们下篇博客见❤️

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2234170.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【工具变量】中国制造2025试点城市数据集(2000-2023年)

数据简介:《中国制造2025》是中国ZF于2015年5月8日印发的一项战略规划,旨在加快制造业的转型升级,提升制造业的质量和效益,实现从制造大国向制造强国的转变。该规划是中国实施制造强国战略的第一个十年行动纲领,明确提…

小菜家教平台(一):基于SpringBoot+Vue打造一站式学习管理系统

前言 现在已经学习了很多与Java相关的知识,但是迟迟没有进行一个完整的实践(之前这个项目开发到一半,很多东西没学搁置了,同时原先的项目中也有很多的问题),所以现在准备从零开始做一个基于SpringBootVue的…

算法专题:字符串

目录 1. 最长公共前缀 1.1 算法原理 1.2 算法代码 2. 最长回文子串 2.1 算法原理 2.2 算法代码 3. 二进制求和 3.1 算法原理 3.2 算法代码 4. 字符串相乘 4.1 算法原理 4.2 算法代码 1. 最长公共前缀 . - 力扣(LeetCode) 1.1 算法原理 有以…

非线性数据结构之图

一、有向图(Directed Graph) 1. 定义 有向图是一个由顶点(节点)和有方向的边(弧)组成的图。在有向图中,每条边都有一个起点和一个终点,表示从一个顶点到另一个顶点的关系。 2. 特…

虚拟现实技术课程开发思路

文章目录 组队选题立项分工建模说明:场景说明:交互说明: 结语: 前言:最近学弟学妹们反馈水水老师课程开始上强度了。不仅有翻转课堂,还有理论课实验课都要做东西出来。听说理论课是做什么博物馆什么的&…

FPGA视频GTH 8b/10b编解码转PCIE3.0传输,基于XDMA中断架构,提供工程源码和技术支持

目录 1、前言工程概述免责声明 2、相关方案推荐我已有的PCIE方案我已有的 GT 高速接口解决方案 3、PCIE基础知识扫描4、工程详细设计方案工程设计原理框图输入Sensor之-->芯片解码的HDMI视频数据组包基于GTH高速接口的视频传输架构GTH IP 简介GTH 基本结构GTH 发送和接收处理…

CSS中常见的两列布局、三列布局、百分比和多行多列布局!

目录 一、两列布局 1、前言: 2. 两列布局的常见用法 两列布局的元素示例: 代码运行后如下: 二、三列布局 1.前言 2. 三列布局的常见用法 三列布局的元素示例: 代码运行后如下: 三、多行多列 1.前言 2&…

jmeter结合ansible分布式压测--1数据准备

一、搭建ansible环境 ansible是基于python开发,通过ssh连接客户机执行任务。ansible可以批量系统配置、批量程序部署、批量运行命令等。 1、安装yum install ansible 2、检查ansible的版本:ansible --version 二、利用ansible在其他机器上准备压测数据 1、本地准…

蓬勃发展:移动开发——关于软件开发你需要知道些什么

一、前言 移动开发一直都是软件开发领域中最有趣的领域之一,这是因为: 1、移动开发为“只有一个人”的开发团队提供了一个非常独特的机会,让他可以在相对较短的时间内建立一个实际的、可用的、有意义的应用程序; 2、移动开发也代…

gitmakegdb

git git reset 命令 | 菜鸟教程 (runoob.com) 像嫁接一样 make Makefile | 爱编程的大丙 (subingwen.cn) # 举例: 有源文件 a.c b.c c.c head.h, 需要生成可执行程序 app ################# 例1 ################# app:a.c b.c c.cgcc a.c b.c c.c -o app################# 例…

网络安全认证的证书有哪些?

在网络安全领域,专业认证不仅是个人技术能力的象征,也是职业发展的重要推动力。随着网络安全威胁的日益严峻,对网络安全专业人才的需求也在不断增长。本文将介绍一些网络安全认证的证书,帮助有志于从事网络安全行业的人士了解并选…

初阶数据结构的各种排序方法——冒泡,直接插入,希尔,快排,选择,归并(C语言)

1.交换排序 交换排序基本思想: 所谓交换,就是根据序列中两个记录键值的⽐较结果来对换这两个记录在序列中的位置 交换排序的特点是:将键值较⼤的记录向序列的尾部移动,键值较⼩的记录向序列的前部移动。 1.1冒泡排序 例子&…

qt QFileInfo详解

1、概述 QFileInfo是Qt框架中用于获取文件信息的工具类。它提供了与操作系统无关的文件属性,如文件的名称、位置(路径)、访问权限、类型(是否为目录或符号链接)等。此外,QFileInfo还可以获取文件的大小、创…

Charles抓包_Android

1.下载地址 2.破解方法 3.安卓调试办法 查看官方文档,Android N之后抓包要声明App可用User目录下的CA证书 3.1.在Proxy下进行以下设置(路径Proxy->Proxy Settings) 3.1.1.不抓包Windows,即不勾选此项,免得打输出不…

软件压力测试有多重要?北京软件测试公司有哪些?

软件压力测试是一种基本的质量保证行为,它是每个重要软件测试工作的一部分。压力测试是给软件不断加压,强制其在极限的情况下运行,观察它可以运行到何种程度,从而发现性能缺陷。 在数字化时代,用户对软件性能的要求越…

【Python】【数据可视化】【商务智能方法与应用】课程 作业一 飞桨AI Studio

作业说明 程序运行和题目图形相同可得90分,图形显示有所变化,美观清晰可适当加分。 import matplotlib.pyplot as plt import numpy as npx np.linspace(0, 1, 100) y1 x**2 y2 x**4plt.figure(figsize(8, 6))# yx^2 plt.plot(x, y1, -., labelyx^2,…

进程的调度(超详细解读)

在特别老的操作系统中,进程的调度是根据FIFO调度算法进行调度,先进先出式的调度,其实就是队列,但是不能很好的体现进程的优先级,在上节讲解的进程优先级,知道nice值范围是[-20,19],然…

【初阶数据结构篇】链式结构二叉树(续)

文章目录 须知 💬 欢迎讨论:如果你在学习过程中有任何问题或想法,欢迎在评论区留言,我们一起交流学习。你的支持是我继续创作的动力! 👍 点赞、收藏与分享:觉得这篇文章对你有帮助吗&#xff1…

【拥抱AI】如何让软件开发在保证数据安全的同时更加智能与高效?

第一、推动软件开发向更加智能化、高效化和创新化方向发展的策略 随着AI技术的不断进步,软件开发正朝着更加智能化、高效化和创新化的方向发展。要实现这一目标,企业需要采取一系列综合性的策略,从技术、管理、文化等多个层面入手。以下是一…

elementUI 点击弹出时间 date-picker

elementUI的日期组件,有完整的UI样式及弹窗,但是我的页面不要它的UI样式,点击的时候却要弹出类似的日期选择器,那怎么办呢? 以下是elementUI自带的UI风格,一定要一个输入框来触发。 这是我的项目中要用到的…