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…...
AI全知道-Embedding model中的Vector知识点
在嵌入模型(Embedding Model)中,向量(Vector)是核心概念之一。向量表示法不仅是数学中的基本工具,也是机器学习和深度学习中处理高维数据的关键手段。本文将深入探讨向量在嵌入模型中的作用、表示方法、计算和应用等知识点。 一、向量的基本概念 向量是一个具有方向和大…...
Qt 学习第四天:信号和槽机制(核心特征)
信号和槽的简介 信号和插槽用于对象之间的通信。信号和插槽机制是Qt的核心特征,可能是不同的部分大部分来自其他框架提供的特性。信号和槽是由Qt的元对象系统实现的。介绍(来自Qt帮助文档Signals & Slots) 在GUI编程中,当我们…...
跳跃游戏Ⅱ C++简单代码
给定一个长度为 n 的 0 索引整数数组 nums。初始位置为 nums[0]。 每个元素 nums[i] 表示从索引 i 向前跳转的最大长度。换句话说,如果你在 nums[i] 处,你可以跳转到任意 nums[i j] 处: 0 < j < nums[i] i j < n 返回到达 nums[n - 1] 的最…...
Gitlab中access token 和Deploy token的区别
在GitLab中,Access Token和Deploy Token是两种不同类型的令牌,用于不同的目的。以下是它们的主要区别: ### Access Token 1. **用途**: - 用于用户身份验证,允许用户以编程方式访问GitLab API。 - 可以用于克隆…...
【多线程】线程的五种创建方法
文章目录 线程在 Java 代码中编写多线程程序Thread 标准库 创建线程的写法1 . 继承 Thread 类代码回调函数休眠操作:sleep()抢占式执行观察线程jconsoleIDEA 内置调试器 2 . 实现 Runnable 接口代码 3. 匿名内部类创建 Thread ⼦类对象代码匿名内部类 4.匿名内部类创…...
关闭窗口工具类 - C#小函数类推荐
此文记录的是一个关于关闭窗口工具类。 /***关闭窗口工具类Austin Liu 刘恒辉Project Manager and Software DesignerE-Mail: lzhdim163.comBlog: http://lzhdim.cnblogs.comDate: 2024-01-15 15:18:00使用方法:CloseWindowUtil.CloseWindow(this.Handle);***/n…...
Xilinx FPGA 原语解析(一):IBUFDS_GTE3 差分时钟输入缓冲器
目录 1.使用说明 2.实例化代码 3.参数解释 4.端口连接 1.使用说明 IBUFDS_GTE3 是Xilinx FPGA 中用于高速接口的差分时钟信号输入缓冲器。 BUFDS_GTEx,x2/3/4(不同系列的FPGA x的值不同),其中UltraScale使IBUFDS_GTE3…...
力扣SQL50 患某种疾病的患者 正则表达式
Problem: 1527. 患某种疾病的患者 在SQL查询中,REGEXP 是用于执行正则表达式匹配的操作符。正则表达式允许使用特殊字符和模式来匹配字符串中的特定文本。具体到你的查询,^DIAB1|\\sDIAB1 是一个正则表达式,它使用了一些特殊的通配符和符号。…...
k8s集群的资源发布方式(滚动/蓝绿/灰度发布)及声明式管理方法
目录 1.常见的发布方式 2.滚动发布 3.蓝绿发布 4.实现金丝雀发布(Canary Release) 5.声明式管理方法 1.常见的发布方式 蓝绿发布:两套环境交替升级,旧版本保留一定时间便于回滚优点:用户无感知,部署和回滚速度较…...
SwiftUI 中掌握 ScrollView 的使用:滚动可见性
文章目录 前言视图修饰符应用场景可见性完整示例ContentViewVideoPlayerViewScrollViewVisibilityApp 总结 前言 我们的滚动 API 中又有一个重要的新增功能:滚动可见性。现在,你可以获取可见标识符列表,或者快速检查并监控 ScrollView 内视图…...
学校网站建设目的/百度快照手机版网页版
关于win7_iis报500.19和500.21错误的解决方法HTTP 错误 500.19 Internal Server Error的解决方法 WIN7下.Net开发遇到的又一问题:HTTP 错误 500.19 - Internal Server Error,无法访问请求的页面,因为该页的相关配置数据无效。 详细错误信息模…...
八戒网站建设/线上推广工作内容
未来 汽车 电子的整个网络将是CAN、LIN、MOST三网合一的整体。MOST负责音视频,CAN负责重要的电子控制单元,如 发动机 、ABS、安全气囊等,LIN负责次要的电子控制单元,如门窗、车灯等。一、CAN总线技术简介CAN总线又称作汽车总线&am…...
自己做的网站能备案吗/b站推广网站入口mmm
Vue3.0 为什么要用 proxy?在 Vue2 中, 0bject.defineProperty 会改变原始数据,而 Proxy 是创建对象的虚拟表示,并提供 set 、get 和 deleteProperty 等处理器,这些处理器可在访问或修改原始对象上的属性时进行拦截&…...
深圳地产网站制作公司/做网站需要准备什么
Python基础8-if选择语句 1 程序结构2、常用选择语句2.1 if语句2.2 if...else语句2.3 if...elif...else语句2.4 if语句的嵌套3 使用and连接条件的选择语句4 使用or连接条件的选择语句5 使用not关键字的选择语句1 程序结构 3种基本结构为:顺序结构、选择结构和循环结构3种结构对…...
cocos2d-js可以做网站吗/国内搜索引擎
文章目录Path绘图基本语法代码例子编译效果Tree绘图基本语法代码例子编译效果除Graphviz外,TikZ也是可以进行数据结构绘图的。以同样的红黑树为例子,用TikZ重新实现一遍。Graphviz的基本模型就是节点和边,这和图算法的两个最基本概念是一样的…...
手机和pc端网站建设/2023免费推广入口
HTML全局属性有哪些? accesskey 设置快捷键 <a hrefwww.baidu.com accesskeyi>可按shift alt i跳转</a> 复制代码class 为元素设置类标识 contenteditable 指定元素内容是否可编辑 data-* 为元素增加自定义属性 dir 设置元素文本方向 <p dirrtl>…...