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底层讲解(重要) operator new 与 operator delete 定位 new 结语 简单回顾C语言动态内存管理 在C语言的学习阶段 我们接触到了三个能在堆上开辟…...

【C语言】结构体内存布局解析——字节对齐
🦄个人主页:小米里的大麦-CSDN博客 🎏所属专栏:https://blog.csdn.net/huangcancan666/category_12718530.html 🎁代码托管:黄灿灿 (huang-cancan-xbc) - Gitee.com ⚙️操作环境:Visual Studio 2022 目录 一、引言 二、什么是字节对齐&…...
模型表达方式
目录 一、模型表达概述 二、模型精确表达 2.1 几何表示 (Geometrical Representation) 三、模型非精确表达 3.1 网格表示 (Mesh Representation) 3.2 体素表示 (Voxel Representation) 一、模型表达概述 模型的表达方式多种多样,选择适合的表达方式取决于具体应用场景和…...

校园课程助手【4】-使用Elasticsearch实现课程检索
本节将介绍本项目的查询模块,使用Elasticsearch又不是查询接口,具体流程如图所示(如果不了解Elasticsearch可以使用sql语句进行查询): 这里是两种方法的异同点: Mysql:擅长事务类型操作&#…...
经典运维面试题
1、Linux常见的日志文件都有哪些,各自的用途?日志轮询配置文件在哪里?欢迎界面配置文件在哪里? /var/log/messages #内核及公共消息日志/var/log/cron #计划任务日志/var/log/dmesg #系统引导日志/var/log/malilog #邮件系…...

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

大厂linux面试题攻略五之数据库管理
一、数据库管理-MySQL语句 0.MySQL基本语句: 1.SQL语句-增 创建xxx用户: mysql>create user xxx % indentified by 123456; xxx表示用户名 %b表示该用户用来连接数据库的方式(远程或本地连接) indentified by 123456设置密码…...
【pytorch】模型集成
在集成学习中,我们会训练多个模型(通常称为「弱学习器」)解决相同的问题,并将它们结合起来以获得更好的结果。最重要的假设是:当弱模型被正确组合时,我们可以得到更精确和/或更鲁棒的模型。 常用的模型集成…...

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

cocos creator 3.x中动态加载 resources 文件夹下的图片时提示找不到
文件目录如下 类型为spriteFrame 代码案例 图片设置为 sprite-frame、texture 或其他图片类型后,将会在 资源管理器 中生成一个对应类型的资源。但如果直接加载 equipments/testea,得到的类型将会是 ImageAsset,必须指定路径到具体的子资源…...
第九十八周周报
学习时间: 2024.7.27-204.8.3 学习产出: 这周主要在按照审稿人的意见修改论文,由于有个模型保存的文件找不到了,所以重新训练花了点时间,目前已经把修改后的论文和cover letter发给杨老师了。...
程序员找工作之数据结构面试题总结分析
文章目录 1. 数据结构的基本概念与分类2. 数据结构的存储与表示3. 数据元素的存储与关系4. 存储结构的选择与考量5. 特定数据结构的定义与特性6. 数据结构操作与应用7. 数组与存储8. 特定数据结构的存储与访问 程序员在找工作面试中,数据结构方面可能会被问到的问题…...
设置provider解决maven找不到JUnit 5测试样例
问题描述 尝试复现一个用大模型生成测试样例的工作,但使用maven生成的JUnit 5测试样例死活不执行。又不想用命令行运行,因此进行排查 基本知识 <dependencies> junit-jupiter-api JUnit 5写代码时调用的库 junit-jupyter-engine 运行JUnit 5测…...

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

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

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

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

JAVA基础知识点3 (String 和 StringBuffer 以及 StringBuilder 的特点以及区别)
1,String 和 StringBuffer 以及 StringBuilder 的特点 (1)String的特点:String是final修饰的字符序列是不可改变的, 是字符串常量,一旦初始化就不可以被更改,因此是线程安全的 因为是常量每次对其操作都会…...

2024年8月AI内容生成技术的现状与未来:从文生文到跨模态交互的全景分析
2024年8月AI内容生成技术的现状与未来:从文生文到跨模态交互的全景分析 大家好,我是猫头虎!🚀 随着AI在内容生成领域的爆发式发展,从2022年末开始,AI生成技术已经走过了文生文(AIGC)…...

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

使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...

超短脉冲激光自聚焦效应
前言与目录 强激光引起自聚焦效应机理 超短脉冲激光在脆性材料内部加工时引起的自聚焦效应,这是一种非线性光学现象,主要涉及光学克尔效应和材料的非线性光学特性。 自聚焦效应可以产生局部的强光场,对材料产生非线性响应,可能…...
C++:std::is_convertible
C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...
模型参数、模型存储精度、参数与显存
模型参数量衡量单位 M:百万(Million) B:十亿(Billion) 1 B 1000 M 1B 1000M 1B1000M 参数存储精度 模型参数是固定的,但是一个参数所表示多少字节不一定,需要看这个参数以什么…...
k8s从入门到放弃之Ingress七层负载
k8s从入门到放弃之Ingress七层负载 在Kubernetes(简称K8s)中,Ingress是一个API对象,它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress,你可…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...

练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
【位运算】消失的两个数字(hard)
消失的两个数字(hard) 题⽬描述:解法(位运算):Java 算法代码:更简便代码 题⽬链接:⾯试题 17.19. 消失的两个数字 题⽬描述: 给定⼀个数组,包含从 1 到 N 所有…...

新能源汽车智慧充电桩管理方案:新能源充电桩散热问题及消防安全监管方案
随着新能源汽车的快速普及,充电桩作为核心配套设施,其安全性与可靠性备受关注。然而,在高温、高负荷运行环境下,充电桩的散热问题与消防安全隐患日益凸显,成为制约行业发展的关键瓶颈。 如何通过智慧化管理手段优化散…...

Maven 概述、安装、配置、仓库、私服详解
目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...