当前位置: 首页 > news >正文

C++ | 动态内存管理 new、delete (用法、底层)详解

目录

简单回顾C语言动态内存管理

new、delete的用法

内置类型

new

delete

自定义类型

new、delete底层讲解(重要)

operator new 与 operator delete

定位 new

结语


简单回顾C语言动态内存管理

在C语言的学习阶段

我们接触到了三个能在堆上开辟空间的函数——malloc、calloc、realloc

其中,malloc是开辟空间但是不初始化,calloc是开辟空间并且会将空间内容都初始化为0,而realloc则主要用于扩容,如果传入的指针为空,则效果和malloc一致

realloc又分为原地扩容和异地扩容

原地扩容就是扩容后的空间直接在原空间上往后延申,但有一个前提,就是在后扩展这段空间里面不能存在数据阻挡,否则就会变成异地扩

异地扩容就是原空间后面有被使用的空间,导致无法直接原地扩容,就需要另外开辟一块完整空间,最后再将数据拷贝到新空间,原空间销毁

但是在C++就不一样了,C++中的new会更为简洁,各位看官且往下看

new、delete的用法

内置类型

new

我们在C++如果要使用C语言中的malloc、calloc、realloc也是可以的,因为C++兼容C语言

但是日常没有人会这么用,因为有更好的选择——new

我们在C++中如果想要动态开辟一个空间,可以选择直接new,如下:

int main()
{//动态开辟一块空间int* ptr = new int;return 0;
}

如果我们要连续开辟一段空间呢?比如开辟10个,如下:

int main()
{//动态开辟一块空间int* ptr1 = new int;//动态开辟一段空间int* ptr2 = new int[10];return 0;
}

那如果我想要开辟了空间之后进行初始化呢?也是可以的,我们先来看单单开辟了一个空间的情况:

int main()
{//动态开辟一块空间并初始化int* ptr1 = new int(5);return 0;
}

接着我们再来看一看一段空间的情况:

int main()
{//动态开辟一段空间并初始化int* ptr2 = new int[10] {1, 2, 3, 4, 5, 6};return 0;
}

如上,我们会看到我们开辟了一段空间,如果要初始化的话,后面就需要跟上花括号{},而如上代码我们只输入了6个数字,这也就代表着我们对应的初始化了前六个,而后面剩下的四个则会默认初始化为0

delete

同样的,C语言中清除空间有free,在C++中对应有delete,如下展示几个例子:

int main()
{//动态开辟一块空间int* ptr1 = new int;delete ptr1;//动态开辟一块空间并初始化int* ptr2 = new int(5);delete ptr2;//动态开辟一段空间int* ptr3 = new int[10];delete[] ptr3;//动态开辟一段空间并初始化int* ptr4 = new int[10] {1, 2, 3, 4, 5, 6};delete[] ptr4;return 0;
}

如上我们可以看到,C++中的delete一共有俩种用法——delete、delete[]

当只有单独一个空间的时候,就使用delete

当有一段空间的时候,就使用delete[]

当然这也比较好记,因为这也和new一一对应

如上都是针对内置类型的情况,但其实祖师爷搞出这块儿主要针对的是自定义类型

自定义类型

我们先来写一个类,在该类的构造函数和析构函数里面分别打印一些内容方便我们检查结果

struct A
{A(){cout << "A()" << " ";}~A(){cout << "~A()" << " " ;}
};

然后我们再使用我们的new:

int main()
{A* a1 = new A;delete a1;cout << endl << endl;A* a2 = new A[10];cout << endl;delete[] a2;return 0;
}

我们可以看到,当我们使用了new来开辟一块A类型的空间的时候,他会在开辟空间的同时,还会调用对应的构造函数

如果是开辟了一段空间比如10个的话,就会连续调用10次构造函数并开辟对应大小的空间

而我们的delete就相反,他会调用对应的析构,如果是连续的就连续调用多次析构并销毁相应空间

new、delete底层讲解(重要)

operator new 与 operator delete

operator new 和 operator delete对标的是malloc和free

也就是说,这个就是开辟空间的,如果我们去看源码的话,我们会发现,operator new 其实就是对malloc的一个封装,operator new 的底层就是malloc,operator delete同理

但是好好的为什么要对 malloc 封装呢?直接用 malloc 不好吗?

各位回想一下,我们每次在使用完malloc之后,都需要检查一下空间有没有开辟成功,如果没有开辟成功,我们还需要进行返回,而且每写一个就需要检查一下,写10个malloc就需要对应写10个检查,这样子写得确实有点恼火

而在C语言种检查错误用的是错误码,是errno

但是C++使用了一种给更好的方法——异常(这个知识太超纲了,后面会重点学,这里知道即可)

所以本质上,operator new 就是对 malloc 和异常进行了一个封装,这也就使得C++中的new变得异常简洁,因为我们不需要检查,直接使用new即可,new里面有operator new,operator new 有malloc 和异常,所以我们不需要检查

但是我们上面又看到,开辟一个自定义类型的时候,还会调用其构造函数

综上,我们可以 得出一个结果:

new = operator new + 构造函数

operator new = malloc + 异常(错误检查)

相对的,delete也是大差不差,但是operator delete可没有异常,祖师爷在这块设计成这样单纯是为了对称,所以:

delete = operator delete+ 析构函数

operator delete = free

同理,再来看看 new[],其本质就是多次调用operator new和构造,仅此而已,delete[] 同理

也就是在内部会多开四个字节用来记录连续开了几块空间,再根据这四个字节里面的内容,来决定到底要调用几次构造,几次析构,简图如以下(假设连续开辟10个空间):

定位 new

一般情况下,我们会使用new,而new会自动调用构造函数

但是我们会遇到一个情况,这个情况出现在内存池中:我们如果频繁地申请空间,会使效率变低,所以就有了内存池,要申请先申请一大块空间,需要申请就到内存池中申请,内存池空间不够了再到堆里面去

但是,我们如果要在内存池中申请空间的话,就不能使用new,因为new默认会调用堆上面的空间,所以我们只能使用operator new,但是我们这时候需要在类外面调用构造,可是析构能在类外面显式调用,但是构造不行,所以就有了定位new的产生

定位new的语法有点子奇怪:

new (place_address) type或者new (place_address) type(initializer-list)

举个例子:

A* ptr = (A*)operator new(sizeof(A));
new(ptr)A(10); //定位newptr->~A();
operator delete(ptr);

如上这是只申请一块空间的情况,但如果是operator new[]的话,就应该写一个for循环,循环的次数就是需要调用构造函数的次数

A* ptr = (A*)operator new(sizeof(A) * 10);
for(int i = 0; i < 10; i++)new(ptr+i)A(5); //定位newfor(int i = 0; i < 10; i++)(ptr+i)->~A();
operator delete[](ptr);

结语

这篇博客详细讲解了C++中的动态内存管理,如果觉得对你有帮助的话,希望可以多多支持!!❀

相关文章:

C++ | 动态内存管理 new、delete (用法、底层)详解

目录 简单回顾C语言动态内存管理 new、delete的用法 内置类型 new delete 自定义类型 new、delete底层讲解&#xff08;重要&#xff09; operator new 与 operator delete 定位 new 结语 简单回顾C语言动态内存管理 在C语言的学习阶段 我们接触到了三个能在堆上开辟…...

【C语言】结构体内存布局解析——字节对齐

&#x1f984;个人主页:小米里的大麦-CSDN博客 &#x1f38f;所属专栏:https://blog.csdn.net/huangcancan666/category_12718530.html &#x1f381;代码托管:黄灿灿 (huang-cancan-xbc) - Gitee.com ⚙️操作环境:Visual Studio 2022 目录 一、引言 二、什么是字节对齐&…...

模型表达方式

目录 一、模型表达概述 二、模型精确表达 2.1 几何表示 (Geometrical Representation) 三、模型非精确表达 3.1 网格表示 (Mesh Representation) 3.2 体素表示 (Voxel Representation) 一、模型表达概述 模型的表达方式多种多样,选择适合的表达方式取决于具体应用场景和…...

校园课程助手【4】-使用Elasticsearch实现课程检索

本节将介绍本项目的查询模块&#xff0c;使用Elasticsearch又不是查询接口&#xff0c;具体流程如图所示&#xff08;如果不了解Elasticsearch可以使用sql语句进行查询&#xff09;&#xff1a; 这里是两种方法的异同点&#xff1a; Mysql&#xff1a;擅长事务类型操作&#…...

经典运维面试题

1、Linux常见的日志文件都有哪些&#xff0c;各自的用途&#xff1f;日志轮询配置文件在哪里&#xff1f;欢迎界面配置文件在哪里&#xff1f; /var/log/messages #内核及公共消息日志/var/log/cron #计划任务日志/var/log/dmesg #系统引导日志/var/log/malilog #邮件系…...

别再盲目推广了!Xinstall助你开启App线下推广新篇章

在这个数字化飞速发展的时代&#xff0c;App已经成为我们生活中不可或缺的一部分。然而&#xff0c;App市场的竞争也日益激烈&#xff0c;如何让你的App在众多竞争者中脱颖而出&#xff0c;成为每个推广者必须面对的问题。今天&#xff0c;就让我们一起探讨一下App线下推广的痛…...

大厂linux面试题攻略五之数据库管理

一、数据库管理-MySQL语句 0.MySQL基本语句&#xff1a; 1.SQL语句-增 创建xxx用户&#xff1a; mysql>create user xxx % indentified by 123456; xxx表示用户名 %b表示该用户用来连接数据库的方式&#xff08;远程或本地连接&#xff09; indentified by 123456设置密码…...

【pytorch】模型集成

在集成学习中&#xff0c;我们会训练多个模型&#xff08;通常称为「弱学习器」&#xff09;解决相同的问题&#xff0c;并将它们结合起来以获得更好的结果。最重要的假设是&#xff1a;当弱模型被正确组合时&#xff0c;我们可以得到更精确和/或更鲁棒的模型。 常用的模型集成…...

初识集合和数据结构

目录 初识集合框架数据结构基本概念和术语数据数据元素数据项数据对象前四者的关系数据结构逻辑结构和物理结构逻辑结构物理结构 算法算法设计要求 初识集合框架 Java的集合框架也可被称为容器&#xff0c;是定义在Java.util包下的一些接口和实现类。其就是将多个元素存储到一…...

cocos creator 3.x中动态加载 resources 文件夹下的图片时提示找不到

文件目录如下 类型为spriteFrame 代码案例 图片设置为 sprite-frame、texture 或其他图片类型后&#xff0c;将会在 资源管理器 中生成一个对应类型的资源。但如果直接加载 equipments/testea&#xff0c;得到的类型将会是 ImageAsset&#xff0c;必须指定路径到具体的子资源…...

第九十八周周报

学习时间&#xff1a; 2024.7.27-204.8.3 学习产出&#xff1a; 这周主要在按照审稿人的意见修改论文&#xff0c;由于有个模型保存的文件找不到了&#xff0c;所以重新训练花了点时间&#xff0c;目前已经把修改后的论文和cover letter发给杨老师了。...

程序员找工作之数据结构面试题总结分析

文章目录 1. 数据结构的基本概念与分类2. 数据结构的存储与表示3. 数据元素的存储与关系4. 存储结构的选择与考量5. 特定数据结构的定义与特性6. 数据结构操作与应用7. 数组与存储8. 特定数据结构的存储与访问 程序员在找工作面试中&#xff0c;数据结构方面可能会被问到的问题…...

设置provider解决maven找不到JUnit 5测试样例

问题描述 尝试复现一个用大模型生成测试样例的工作&#xff0c;但使用maven生成的JUnit 5测试样例死活不执行。又不想用命令行运行&#xff0c;因此进行排查 基本知识 <dependencies> junit-jupiter-api JUnit 5写代码时调用的库 junit-jupyter-engine 运行JUnit 5测…...

php反序列化靶机serial实战

扫描ip,找到靶机ip后进入 他说这是cookie的测试网页&#xff0c;我们抓个包&#xff0c;得到cookie值 base64解码 扫描一下靶机ip的目录 发现http://192.168.88.153/backup/&#xff0c;访问 下载一下发现是他的网页源码 通过代码审计&#xff0c;发现 通过代码审计得知&…...

类型推断技术及仓颉语言实践

史磊 仓颉语言类型推断技术专家 一、一种看待类型系统的方式 一门编程语言一定得包含类型系统吗&#xff1f; 这个问题今天看来可能显而易见&#xff0c;一个程序没有类型的话还能算是个完整、正确的程序吗&#xff1f;但是其实关于类型系统的作用&#xff0c;一直是存在两种…...

职场生存秘籍:16条黄金法则

作者简介&#xff1a;一名计算机萌新、前来进行学习VUE,让我们一起进步吧。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;我叫于豆豆吖的主页 写在前面 在这个瞬息万变的时代&#xff0c;职场不仅是实现个人价值与梦想的舞台&#xff0c;更是一…...

Flask 介绍

Flask 介绍 为什么要学 Flask框架对比设计哲学功能特点适用场景学习曲线总结 Flask 的特点Flask 常用扩展包Flask 的基本组件Flask 的应用场景官方文档官方文档链接文档内容概述学习建议 Flask 是一个使用 Python 编写的轻量级 Web 应用框架。它旨在让 Web 开发变得快速、简单且…...

JAVA基础知识点3 (String 和 StringBuffer 以及 StringBuilder 的特点以及区别)

1&#xff0c;String 和 StringBuffer 以及 StringBuilder 的特点 &#xff08;1&#xff09;String的特点&#xff1a;String是final修饰的字符序列是不可改变的&#xff0c; 是字符串常量&#xff0c;一旦初始化就不可以被更改,因此是线程安全的 因为是常量每次对其操作都会…...

2024年8月AI内容生成技术的现状与未来:从文生文到跨模态交互的全景分析

2024年8月AI内容生成技术的现状与未来&#xff1a;从文生文到跨模态交互的全景分析 大家好&#xff0c;我是猫头虎&#xff01;&#x1f680; 随着AI在内容生成领域的爆发式发展&#xff0c;从2022年末开始&#xff0c;AI生成技术已经走过了文生文&#xff08;AIGC&#xff09…...

File 34

package File;import java.awt.*; import java.io.File;public class file1 {public static void main(String[] args) {//创建FILE对象&#xff0c;指代某个具体的文件//路径分隔符File f1new File("C:/Users/SUI/Desktop/kaishi/nih.txt");// File f1new File(&quo…...

XML Group端口详解

在XML数据映射过程中&#xff0c;经常需要对数据进行分组聚合操作。例如&#xff0c;当处理包含多个物料明细的XML文件时&#xff0c;可能需要将相同物料号的明细归为一组&#xff0c;或对相同物料号的数量进行求和计算。传统实现方式通常需要编写脚本代码&#xff0c;增加了开…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

屋顶变身“发电站” ,中天合创屋面分布式光伏发电项目顺利并网!

5月28日&#xff0c;中天合创屋面分布式光伏发电项目顺利并网发电&#xff0c;该项目位于内蒙古自治区鄂尔多斯市乌审旗&#xff0c;项目利用中天合创聚乙烯、聚丙烯仓库屋面作为场地建设光伏电站&#xff0c;总装机容量为9.96MWp。 项目投运后&#xff0c;每年可节约标煤3670…...

精益数据分析(97/126):邮件营销与用户参与度的关键指标优化指南

精益数据分析&#xff08;97/126&#xff09;&#xff1a;邮件营销与用户参与度的关键指标优化指南 在数字化营销时代&#xff0c;邮件列表效度、用户参与度和网站性能等指标往往决定着创业公司的增长成败。今天&#xff0c;我们将深入解析邮件打开率、网站可用性、页面参与时…...

USB Over IP专用硬件的5个特点

USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中&#xff0c;从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备&#xff08;如专用硬件设备&#xff09;&#xff0c;从而消除了直接物理连接的需要。USB over IP的…...

蓝桥杯 冶炼金属

原题目链接 &#x1f527; 冶炼金属转换率推测题解 &#x1f4dc; 原题描述 小蓝有一个神奇的炉子用于将普通金属 O O O 冶炼成为一种特殊金属 X X X。这个炉子有一个属性叫转换率 V V V&#xff0c;是一个正整数&#xff0c;表示每 V V V 个普通金属 O O O 可以冶炼出 …...

return this;返回的是谁

一个审批系统的示例来演示责任链模式的实现。假设公司需要处理不同金额的采购申请&#xff0c;不同级别的经理有不同的审批权限&#xff1a; // 抽象处理者&#xff1a;审批者 abstract class Approver {protected Approver successor; // 下一个处理者// 设置下一个处理者pub…...

使用LangGraph和LangSmith构建多智能体人工智能系统

现在&#xff0c;通过组合几个较小的子智能体来创建一个强大的人工智能智能体正成为一种趋势。但这也带来了一些挑战&#xff0c;比如减少幻觉、管理对话流程、在测试期间留意智能体的工作方式、允许人工介入以及评估其性能。你需要进行大量的反复试验。 在这篇博客〔原作者&a…...

基于IDIG-GAN的小样本电机轴承故障诊断

目录 🔍 核心问题 一、IDIG-GAN模型原理 1. 整体架构 2. 核心创新点 (1) ​梯度归一化(Gradient Normalization)​​ (2) ​判别器梯度间隙正则化(Discriminator Gradient Gap Regularization)​​ (3) ​自注意力机制(Self-Attention)​​ 3. 完整损失函数 二…...

【Linux】Linux 系统默认的目录及作用说明

博主介绍&#xff1a;✌全网粉丝23W&#xff0c;CSDN博客专家、Java领域优质创作者&#xff0c;掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域✌ 技术范围&#xff1a;SpringBoot、SpringCloud、Vue、SSM、HTML、Nodejs、Python、MySQL、PostgreSQL、大数据、物…...