C++内存管理(1)

目录

1.new用法说明

2.new/delete在栈里面的运用

3.operator new/operator delete函数

4.构造函数的显式调用

5.malloc&&new&&free&&delete区别


1.new用法说明

(1)在C语言阶段,我们无论是为数组开辟空间,还是为单个的内置数据类型的数据开辟空间,都是使用malloc,realloc,calloc这些函数,但是C++里面引入了类和对象,这个时候,我们是没有办法使用C语言里面的那些函数为类开辟空间的;

(2)我们使先看一下new为单个的内置数据类型开辟空间的使用方法:

这个就是C语言和C++的不同的写法,C语言需要进行强制类型转换,但是C++不需要;

在C++里面,我们可以直接使用new为int类型的数据开辟空间写法就如同上面的,而且C++里面使用new开辟空间的时候,不需要进行强制类型的转换,我们在开辟完成之后可以直接进行初始化的操作,初始化的方法就是上面展示的在int后面加上一个括号,括号里面的数值就是我们想要初始化的数值;

(3)new为数组开辟空间

数组开辟空间的方式稍有不同,因为数组里面有很多个数据,我们需要在int后面加上中括号,里面的数据就是数组里面的元素的个数;

初始化的方法就如同上面展示的那样,在[10]后面加上大括号,里面写入的就是我们想要初始化的结果,我们这个案例是对数组里面的前三个元素进行初始化,后面的其他的元素默认初始化的结果是0;

(4)手动开辟空间的释放

我们在学习C语言的时候,是使用free进行空间的释放,在C++里面,我们引入了delete进行释放空间,delete的使用方法,如下所示:

我们还是分为单个数据的释放和数组的整体空间的释放进行介绍 :

显然,数组和单个数据类型的不同就在于数组是在delete后面加上了方括号来进行标识;

(5)类创建的对象的释放

如果仅仅是为了方便代码的简洁性,祖师爷肯定不会发明new这个东西出来,任何一个事物的出现必然是可以解决一类问题的,这个new是可以解决malloc这些函数无法完成的问题的,因为malloc是没有办法对我们的类创建的对象进行空间的开辟的,因为malloc根本就不认识这个类和对象,这个时候就有new和delete的用武之地了;

这里还是使用相同的方法,只不过把原来的内置数据类型转换为我们现在的自定义的数据类型,其他都是不变的;

但是这里必须要在类里面写出构造函数(初始化列表进行初始化,有缺省参数),否则我们在对A里面的p02进行初始化的时候就会报错(这里建议我们以后进行初始化的时候尽量使用初始化列表的方式);

 我们也可以使用隐式类型转换和匿名对象的方式对这个数组元素进行初始化:

 (6)new/delete和malloc/free最大的区别就是,new/delete对于自定义类型的数据,除了会进行空间的开辟,还会调用对应的构造函数; 

(7)使用new创建链表里面的节点

之前我们是使用buynode这个函数进行节点的创建的,现在我们可以使用new进行创建节点,而且我们可以直接进行初始化的操作。

2.new/delete在栈里面的运用

(1)我们使用栈举例,可以更好地理解new /delete的用法,我们都知道对于一个栈而言,是有一个数组,一个变量记录数组的容量,一个变量用来记录数组里面的元素的个数;

(2)当我们使用new的时候,这个时候开辟的是栈的空间,就是上面的图片里面的正方形的那片空间,当我们在使用new开辟空间的时候,因为这个时候就会调用默认的构造函数,这个时候调用默认构造函数的时候就会为栈里面的数组元素开辟空间;

(3)当我们使用delete释放空间的时候,首先调用析构函数释放掉我们为数组元素开辟的空间,然后是使用delete释放掉栈的空间。

3.operator new/operator delete函数

(1)首先在这里声明一下,上面的这两个是函数,虽然和我们之前学过的运算符重载长得很像,但是这个是标准库里面的两个函数,不是运算符重载;

(2)了解这两个函数,可以让我们更加清晰的认识new的底层逻辑:就是我们每次使用new进行空间的开辟的时候,实际上是调用的operator函数和构造函数,而这里的operotor函数实际上就是对于malloc的一个封装,不同的地方就在于我们的malloc开辟空间失败就是返回0,但是这个封装malloc的operator new函数实际上,当空间没有开辟成功的时候,不会返回0,而是抛出异常;

(3)抛出异常就是对于错误的代码就不会执行了,基本的格式就是try catch语句,try里面的就是执行语句,当我们在try里面的语句出现问题的时候,就会跳过try里面错误语句后面的代码,通过catch打印错误原因;

(4)这个operator new/operator delete函数不是给我们使用的,是给标准库使用的,我们一般不会使用到;

(5)可见,C++里面的new并不是特别神秘,只是在封装函数的基础上面加上构造函数,有了new,我们就可以不用判断if(……==NULL)perror这样的判断,而是在失败的时候利用try---catch语句抛出异常,这样其实更加符合C++的机制和报错原理;

(7)在C++里面是兼容C语言的,所以我们在使用new进行空间的开辟的时候,也是可以使用free进行空间的释放的,但是这个并不代表我们可以随意的使用;

实际上,我们在写析构函数和不写析构函数的时候,我们的编译器的执行原理是不一样的,这个地方那个我们只需要记住,不要把new和free混用,一定要匹配使用才行,否则就会出现意想不到的报错,就是使用new int 开辟空间,就是用delete释放空间,使用new int [10]开辟数组空间,就使用delete[ ] int进行空间的释放,不要把C++的delete和C语言的free混合使用,仅此而已。

4.构造函数的显式调用

(1)我们这里是使用一个栈作为例子,我们可以在82行显式调用Stack的析构函数,但是我们没有办法像79行一样显式调用构造函数;

(2)我们想要显式调用构造函数,就要像80行一样进行表示,这样才能够显式调用构造函数,但是这样的表示方法我们一般不会使用;

(3)这个语法有很多种叫法,例如定位new表达式,或者有的叫做replacement new都是可以的,我们下面还可以使用一个类介绍一下:

 上面的这个就比栈的那个更加完整,更加易于我们进行理解,实际上我们通过这两个对比更能够说明问题:

Stack和这里的A本质都是一样的,我们开辟空间的时候malloc和operator new本质都是一样的,也就可以理解为两者实现的效果是一样的;

我们在进行显示调用的时候都是new(定义的变量)类的名字;

实际上这个定位new这个语法适合内存池结合使用的,我们现在了解即可,因为我们一般不会这样使用,内存池里面的呢内存不会进行初始化的操作,因此我们需要像现在这样显示的调用构造函数进行初始化的操作,仅此而已。

5.malloc&&new&&free&&delete区别

(1)对于这两者的区别以及他们之间的比较,我们主要是通过用法以及他们的底层原理进行介绍的;

(2)在使用方法上面,malloc和free都是函数,但是delete和new都是操作符;

(3)malloc不会进行初始化的操作,但是我们的new操作符可以进行初始化,初始化的方法就是对于单个的变量,我们可以使用小括号进行初始化,对于这个数组里面的多个元素的情况,我们可以使用花括号的方式进行初始化的操作;

(4)malloc申请空间的时候,需要我们手动的进行计算空间的大小,但是如果我们使用new进行空间的开辟的时候,就可以直接在new后面加上数据的类型就可以了,是不需要我们进行手动的释放的,而且对于数组类型的,我们可以直接在new后面类型后面加上中括号里面写上数组里面的元素的个数即可;

(5)malloc需要进行强制类型的转换,但是new不需要,因为new的后面就是数据的类型;

(6)malloc申请空间失败的时候,返回值是NULL,而且我们需要进行判断是否开辟空间成功,但是对于new而言,就不会出现这个情况,因为new开辟空间失败的话就会抛出异常;

(7)对于底层原理而言,我们的malloc就会进行空间的开辟,不会调用构造函数和析构函数,但是new开辟空间的时候,就会调用构造函数完成对于对象的初始化,delete进行空间的释放的时候,就会调用析构函数进行对象的销毁,完成资源的清理;

(8)总的来说,我们需要从两个方面认识到为什么C++里面要引入new和delete,

一方面就是为了让我们对于空间的开辟的时后,更加简洁,这个简洁体现在

不用进行初始化,

不用担心开辟失败的问题,

不用进行强制类型的转换,

不用在多个数据的时候计算空间的大小;

另一方面就是解决对于自定义类型的空间开辟的问题,让这个delete、new自动调用析构函数和构造函数进行空间的初始化以及内容的清理工作。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

瀚高数据库(HighGoDB)Windows安装使用

1.下载 2.安装 瀚高数据库下载与安装(Windows版)-CSDN博客 3.连接工具 4.建库、建表操作 瀚高数据库管理工具-CSDN博客 *报错Cant access non-default database,需要右键数据库-设为活动对象 5.导入外部数据(迁移、对比&…

云贝教育 |【好课上新】ITSS服务工程师与服务经理认证培训

课程前言 ITSS是中国电子技术标准化研究院推出的,包含“IT 服务工程师”和“IT 服务经理”的系列培训。有效满足GB/T 28827.1 的符合性评估要求和ITSS服务资质升级要求。 IT 服务工程师”结合 IT服务从业人员能力规范和要求,从服务技术、服务技巧和服务…

Linux环境下parted工具使用

在工作中,我们经常会遇到大于分区大于2T的磁盘,由于系统盘最大不能超2T,我们会在做raid时将划分VD来进行装系统,但系统自动安装后无法将磁盘全部识别出来,管理员有时会要求手动对分区进行挂载,这个文档介绍…

基于PSO粒子群优化的PV光伏发电系统simulink建模与仿真

目录 1.课题概述 2.系统仿真结果 3.核心程序与模型 4.系统原理简介 4.1 粒子群优化算法基础 4.2 PV系统及其最大功率点跟踪 4.3 PSO在PV MPPT中的应用 5.完整工程文件 1.课题概述 基于PSO粒子群优化的PV光伏发电系统simulink建模与仿真。通过PSO粒子群优化进行最大功率…

Day25 代码随想录打卡|栈与队列篇---用队列实现栈

题目(leecode T225): 请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。 实现 MyStack 类: void push(int x) 将…

每日OJ题_贪心算法四④_力扣397. 整数替换

目录 力扣397. 整数替换 解析代码 力扣397. 整数替换 397. 整数替换 难度 中等 给定一个正整数 n ,你可以做如下操作: 如果 n 是偶数,则用 n / 2替换 n 。如果 n 是奇数,则可以用 n 1或n - 1替换 n 。 返回 n 变为 1 所需…

C# Linq中的自定义排序

1.开发过程中&#xff0c;会遇到OrderBy/OrderByDescending排序无法满足的情况&#xff0c;此时就需要自定义排序&#xff0c;按照想要的排序规则取排序&#xff0c;比如订单的状态等等。 2.自定义泛型比较器代码如下&#xff1a; /// <summary>/// 自定义泛型比较器(用…

【ArcGIS 小技巧脚本工具】批量修复CAD图层的数据源

当你打开ArcPro文档的时候&#xff0c;看到内容列表满屏红色感叹号。 新手可能会心脏骤停&#xff0c;久经沙场的规划人只会微微一笑。随机选中一个幸运的红色感叹号点击&#xff0c;打开更改数据源对话框&#xff0c;找到它原始的数据源&#xff0c;确定。 but。。。为啥只修复…

将CentOS 7安装在U盘上,这时你将体验到......

文章目录 前言一、Linux 是什么&#xff1f;二、使用步骤1.下载安装 VMware Workstation Pro2.下载 CentOS 镜像3.准备一个U盘&#xff08;最好是32G以上的&#xff09;4.VMware 里安装 CentOS 总结 前言 随着 Linux 在服务器、嵌入式系统、移动设备等领域的广泛应用&#xff…

【通义千问系列】Qwen-Agent 从入门到精通【持续更新中……】

目录 前言一、快速开始1-1、介绍1-2、安装1-3、开发你自己的Agent 二、Qwen-Agent的使用和开发过程2-1、Agent2-1-1、Agent使用2-1-2、Agent开发 2-2、Tool2-2-1、工具使用2-2-2、工具开发 2-3、LLM2-3-1、LLM使用2-3-2、LLM开发 三、基于Qwen-Agent的案例分析3-1、3-2、 总结 …

Linux i2c工具——i2c_tools

1 简介 i2c-tools是一个用于处理I2C&#xff08;Inter-Integrated Circuit&#xff09;总线的工具集&#xff0c;它在Linux环境中广泛使用。这个工具集包含了一系列命令行工具&#xff0c;用于在I2C总线上执行各种操作&#xff0c;例如扫描设备、读取/写入寄存器、检测设备等。…

【jitsi】jitsi 布署及docker打包

目录 单独的布署 最后总结的成果 旧的架构 单独的布署 最后总结的成果 http://10.30.40.10/dualvenDoc/installjitsi/ 旧的架构 wvp视频调度平台架构布署图_wvp 架构-CSDN博客

插入法(直接/二分/希尔)

//稳定耗时&#xff1a; 双向冒泡&#xff0c;可指定最大最小值个数MaxMinNum<nsizeof(Arr)/sizeof(Arr[0]), void BiBubbleSort(int Arr[],int n&#xff0c;int MaxMinNum){int left0,rightn-1;int i;bool notDone true;int temp;int minPos;while(left<right&&am…

【WEEK11】 【DAY6】员工管理系统第七部分【中文版】

2024.5.11 Saturday 接上文【WEEK11】 【DAY5】员工管理系统第六部分【中文版】 目录 10.8.删除及404处理10.8.1.修改list.html10.8.2.修改EmployeeController.java10.8.3.重启10.8.4. 404页面处理10.8.4.1.把404.html文件移入10.8.4.2.重启并运行 10.8.5.退出登录状态10.8.5.1…

Llama3-Tutorial(Llama 3 超级课堂)-- 笔记

第1节—Llama 3 本地 Web Demo 部署 端口转发 vscode里面设置端口转发 https://a-aide-20240416-b4c2755-160476.intern-ai.org.cn/proxy/8501/ ssh -CNg -L 8501:127.0.0.1:8501 rootssh.intern-ai.org.cn -p 43681参考 https://github.com/SmartFlowAI/Llama3-Tutorial/b…

法语语式与时态总结,柯桥零基础学法语

常用语式 法语中的常用语式分为&#xff1a;直陈式、条件式、虚拟式、命令式、不定式与分词式。 直陈式&#xff08;lindicatif&#xff09;初学法语时首先就要学直陈式&#xff0c;也是最常用的语式&#xff0c;表示确实发生的动作。 条件式&#xff08;le conditionnel&am…

图和网络笔记

文章目录 1. 图(节点边) 1. 图(节点边) 一个图可以由节点和边组成&#xff0c;假设我们有一个节点notes &#xff1a;n4,边edges&#xff1a;m5的有向图&#xff0c;表示如下 通过以上电路图可以得到关联矩阵(incident matrix),我们定义边&#xff0c;开始端用-1表示&#x…

如何将Git仓库中的文件打包成zip文件?

要将Git仓库中的文件打包成zip文件&#xff0c;您可以使用git archive命令。这个命令允许您将任何git可访问的树或提交导出成一个归档文件。以下是一些基本的步骤&#xff1a; 打开命令行或终端。切换到您的Git仓库的目录。执行git archive命令。 git archive --formatzip --o…

thinkphp8 framework和 element plus admin前后端分离系统之PHP安装教程

DIYGW-UI-PHP是一款基于thinkphp8 framework和 element plus admin开发而成的前后端分离系统。目的是结合现有diygw-ui打造一个后台API开发。 实现PHP源码前请先下载小皮面板或者宝塔。 系统已经集成了部分功能 用户管理 后台用户管理部门管理 配置公司的部门结构&#xff0…

AIGC、LLM 加持下的地图特征笔记内容生产系统架构设计

文章目录 背景构建自动化内容生产平台系统架构设计架构详细设计流程介绍笔记来源笔记抓取干预 笔记 AIGC 赋能笔记 Rule 改写笔记特征库构建 附录Bash Cron 定时任务Golang 与 Pyhon AIGC 实践 小结 背景 在大模型的浪潮下&#xff0c;ChatGPT、Sora、Gemini、文言一心 等新技…