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

大家好,我是苏貝,本篇博客带大家了解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.mzph.cn/pingmian/59293.shtml

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

相关文章

transformers 框架使用详解,bert-base-chinese

以 bert-base-chinese 模型为例,模型目录 model_name "C:/Users/Administrator.DESKTOP-TPJL4TC/.cache/modelscope/hub/tiansz/bert-base-chinese" bert-base-chinese 模型大小只有400多兆,参数的量级在百万级别,与现在动辄几十…

acmessl.cn提供接口API方式申请免费ssl证书

目录 一、前沿 二、API接口文档 1、证书可申请列表 简要描述 请求URL 请求方式 返回参数说明 备注 2、证书申请 简要描述 请求URL 请求方式 业务参数 返回示例 返回参数说明 备注 3、证书查询 简要描述 请求URL 请求方式 业务参数 返回参数说明 备注 4、证…

使用 JWT 实现安全认证的技术详解

一、概述 **JWT(Json Web Token)** 是一种用于安全地在客户端和服务器之间传递信息的机制。JWT 在网络应用环境中扮演重要角色,特别适合用于分布式系统中的单点登录(SSO),实现跨站点、跨应用的身份验证。 …

【那些年踩过的坑-前端篇- Mac版本】npm init vite 失败,报错`CERT_HAS_EXPIRED npm ERR

CERT_HAS_EXPIRED npm ERR! errno CERT_HAS_EXPIRED npm ERR! request to htt 开发中vue3项目执行npm init vite 命令报错了,vite 需要node.js版本> 12.0.0 beiluobeiluodeMBP vue3-demo % node -v v16.13.0 beiluobeiluodeMBP vue3-demo % npm init vite npm E…

问:Redis常见性能问题及解法?

Redis 作为一个高性能的键值存储系统,在实际应用中可能会遇到各种性能问题。本文将探讨 Redis 的常见性能问题,并提供相应的解决建议。主要针对五个关键问题进行讨论:Master 节点的持久化工作、Slave 节点的数据备份、主从复制的网络环境、主…

【docker】docker 环境配置及安装

本文介绍基于 官方存储库 docker 的环境配置、安装、代理配置、卸载等相关内容。 官方安装文档说明:https://docs.docker.com/engine/install/ubuntu/ 虚拟机环境 Ubuntu 20.04.6 LTS 安装步骤 添加相关依赖 sudo apt-get update sudo apt-get install ca-certifi…

机器学习在时间序列预测中的应用与实现——以电力负荷预测为例(附代码)

📝个人主页🌹:一ge科研小菜鸡-CSDN博客 🌹🌹期待您的关注 🌹🌹 1. 引言 随着数据采集技术的发展,时间序列数据在各个领域中的应用越来越广泛。时间序列预测旨在基于过去的时间数据来…

uniapp+vue加油服务系统 微信小程序

文章目录 项目介绍具体实现截图技术介绍mvc设计模式小程序框架以及目录结构介绍错误处理和异常处理java类核心代码部分展示详细视频演示源码获取 项目介绍 基于微信小程序的加油服务系统设计为微信小程序和后台管理两个服务端,并对此设计相应的功能模块如下&#x…

uniapp使用后会打开很多导航栏

在uniapp中,如果遇到打开过多的导航栏,很可能是因为在页面跳转时没有正确管理导航记录。为了避免这个问题,可以使用uni.navigateBack()来关闭当前页面并返回上一页面,或者使用uni.reLaunch()或uni.redirectTo()来关闭所有页面并跳…

大数据新视界 -- 大数据大厂之 Impala 资源管理:并发控制的策略与技巧(下)(6/30)

💖💖💖亲爱的朋友们,热烈欢迎你们来到 青云交的博客!能与你们在此邂逅,我满心欢喜,深感无比荣幸。在这个瞬息万变的时代,我们每个人都在苦苦追寻一处能让心灵安然栖息的港湾。而 我的…

Linux(CentOS)设置防火墙开放8080端口,运行jar包,接收请求

1、查看防火墙状态 systemctl status firewalld 防火墙开启状态 2、运行 jar 包,使用8080端口 程序正常启动 3、使用 postman 发送请求,失败 4、检查端口是否开放(需更换到 root 用户) firewall-cmd --zonepublic --query-por…

跳表原理-课堂笔记

课程地址 跳表是一种基于随机化的有序数据结构,它提出是为了赋予有序单链表以 O(logn) 的快速查找和插入的能力 创建 首先在头部创建一个 sentinel 节点,然后在 L1 层采用“抛硬币”的方式来决定 L0 层的指针是否增长到 L1 层 例如上图中,L…

Mybatis学习笔记(二)

八、多表联合查询 (一) 多表联合查询概述 在开发过程中单表查询不能满足项目需求分析功能,对于复杂业务来讲,关联的表有几张,甚至几十张并且表与表之间的关系相当复杂。为了能够实业复杂功能业务,就必须进行多表查询&#xff0c…

基于 JAVASSM(Java + Spring + Spring MVC + MyBatis)框架开发一个九宫格日志系统

基于 JAVASSM(Java Spring Spring MVC MyBatis)框架开发一个九宫格日志系统 步骤一:需求分析 明确系统需要实现的功能,比如: 用户注册和登录添加日志(包含标题、内容、图片)查看日志列表…

rom定制系列------小米8青春版定制安卓14批量线刷固件 原生系统

💝💝💝小米8青春版。机型代码platina。官方最终版为 12.5.1安卓10的版本。客户需要安卓14的固件以便使用他们的软件。根据测试,原生pixeExpe固件适配兼容性较好。为方便客户批量进行刷写。修改固件为可fast批量刷写。整合底层分区…

优化协同过滤推荐算法的技术与实践

协同过滤是一种广泛应用于推荐系统的技术,它利用用户的历史行为数据来预测用户对于未见过的内容的偏好。协同过滤有两种主要类型:基于用户的协同过滤和基于物品的协同过滤。此外,随着技术的进步,矩阵分解和深度学习也被应用于协同…

浅谈UI自动化

⭐️前言⭐️ 本篇文章围绕UI自动化来展开,主要内容包括什么是UI自动化,常用的UI自动化框架,UI自动化原理等。 🍉欢迎点赞 👍 收藏 ⭐留言评论 🍉博主将持续更新学习记录收获,友友们有任何问题…

【Docker】错误: read tcp xxx->xxx: read: connection reset by peer

错误代码 ERR-DOCKER-0301 错误类型 下载镜像时报错 错误信息 Error response from daemon: Get "https://registry-1.docker.io/v2/": read tcp 10.0.2.6:35544->44.205.64.79:443: read: connection reset by peer 错误复现 这种错误一般在下载镜像时报错,…

blender导入的图片渲染看不见,图片预览正常,但渲染不出

在使用Blender时,我们经常会遇到导入图片后在预览渲染中显示,但在实际渲染时图片消失的问题。本文将提供详细的解决方法,帮助大家解决“Blender导入的图片渲染图像不显示”的问题。 问题原因 导入的图片在Blender中只是一张图,并…

vue--vueCLI

何为CLI ■ CLI是Command-Line Interface,俗称脚手架. ■ 使用Vue.js开发大型应用时,我们需要考虑代码目录结构、项目结构和部署、热加载、代码单元测试等事情。(vue 脚手架的作用), 而通过vue-cli即可:vue-cli 可以…