C++内存管理(1)

news2024/9/20 10:37:37

目录

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自动调用析构函数和构造函数进行空间的初始化以及内容的清理工作。

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

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

相关文章

Disk Map for Mac,让您的Mac更“轻”松

还在为Mac磁盘空间不足而烦恼吗?Disk Map for Mac来帮您轻松解决!通过独特的TreeMap视觉显示技术,让您一眼就能看出哪些文件和文件夹占用了大量空间。只需简单几步操作,即可快速释放磁盘空间,让您的Mac更“轻”松。快来…

STL-Hashtable

hashtable hashtable是通过某种函数(hashFunc)使元素的存储位置与它的关键码之间能够建立一一映射的关系,这样在查找的时候就可以很快的找到该元素。 哈希函数 哈希函数的定义域必须包括需要存储的全部关键码,而如果散列表允许有m个地址时&#xff0c…

Web UI自动化测试--PO模式

没有PO实现的测试用例的问题: 重用性低:登录功能重复可维护性差:数据和代码混合可读性差:元素定位方法杂乱(id、xpath、css混杂)可读性差:不易识别操作的含义(特别是css和xpath语法)可维护性差:如果某个元素的属性改了,你要更改多次PO(Page Object Model)页面对象模型…

Linux 第二十八章

🐶博主主页:ᰔᩚ. 一怀明月ꦿ ❤️‍🔥专栏系列:线性代数,C初学者入门训练,题解C,C的使用文章,「初学」C,linux 🔥座右铭:“不要等到什么都没有了…

C# SolidWorks 二次开发 -从零开始创建一个插件(3) 发布插件

五一节过完了吧,该上班学习了吧? 如何把自己开发好的程序优雅的给别人使用。 今天我们来简单讲解一下,这个之前不少粉丝咨询过相关问题,自己开发好的东西,如何给同事或者其它人使用。 先列一下使用到的主要工具&am…

计算机毕业设计】springbootBBS论坛系统

本系统为用户而设计制作 BBS论坛系统,旨在实现BBS论坛智能化、现代化管理。本BBS论坛自动化系统的开发和研制的最终目的是将BBS论坛的运作模式从手工记录数据转变为网络信息查询管理,从而为现代管理人员的使用提供更多的便利和条件。使BBS论坛系统数字化…

SpringCloud使用Nacos作为配置中心实现动态数据源切换

一、Nacos-Server 了解Nacos可以直接阅读官方文档 使用Nacos,我们需要有Nacos-Server,此处就不使用官方提供的release版本了,而是自己编译,因为本来就是Java开发的,所以对于Javaer来说也没啥难度! git c…

解决NVM 下载node.js慢问题->最新镜像

一、NVM 介绍 nvm是node版本管理工具,可以运行在多种操作系统上。这里主要记录一下在windows系统的安装和使用。 在使用过程中,下载其他版本时会出现下载慢或卡住或下载失败的情况,是因为服务器在国外,网络原因导致,…

【神经网络】输出层的设计

文章目录 前言一、恒等函数和softmax函数恒等函数softmax 函数python实现softmax函数 二、实现softmax函数时的注意事项函数优化python实现 三、softmax函数的特征计算神经网络的输出输出层的softmax函数可以省略“学习”和“推理”阶段 四、输出层的神经元数量 前言 神经网络…

03.Linux文件操作

1.操作系统与Linux io框架 1.1 io与操作系统 1.1.1 io概念 io 描述的是硬件设备之间的数据交互,分为输⼊ (input) 与输出 (output)。 输⼊:应⽤程序从其他设备获取数据 (read) 暂存到内存设备中;输出:应⽤程序将内存暂存的数据…

FreeRTOS学习笔记-基于stm32(6)时间片调度实验

1、什么是时间片调度 在任务优先级相同的时候,CPU会轮流使用相同的时间去执行它,即时间片调度。这个相同的时间就是时间片。而时间片的大小就是SysTick的中断周期(SysTick的中断周期可以修改)。 比如有三个相同优先级的任务在运行…

基于C++基础知识的指针

一、变量与指针 在C中,变量是用来存储数据的一个标识符,而指针是一个变量,该变量存储的是另一个变量的地址。 变量可以是不同的数据类型,包括整数、浮点数、字符、布尔值等。在声明变量时,需要指定变量的数据类型和标…

差分约束 C++ 算法例题

差分约束 差分约束 是一种特殊的 n 元一次不等式组,m 个约束条件,可以组成形如下的格式: { x 1 − x 1 ′ ≤ y 1 x 2 − x 2 ′ ≤ y 2 ⋯ x m − x m ′ ≤ y m \begin{cases} x_1-x_1^{} \le y_1 \\ x_2-x_2^{} \le y_2 \\ \cdots \\ x_…

TCP的四次挥手过程

TCP连接是双向传输的对等的模式(全双工模式),就是说双方都可以同时向对方发送或接收数据。 而断开的时候,也是双方都可以主动断开,此时需要经过四次挥手的过程,流程如下图所示: 主动方发送FIN包…

HTTP1.1的优化措施

3.2 HTTP/1.1 如何优化? 可以从以下三个方面来优化http/1.1协议: 尽量避免发送 HTTP 请求; 在需要发送 HTTP 请求时,考虑如何减少请求次数; 减少服务器的 HTTP 响应的数据大小; 避免发送HTTP请求 对于…

智能文件夹改名助手:一键秒级恢复原始名称,轻松告别繁琐操作,提升文件管理效率

文件夹管理成为了我们日常工作和生活中不可或缺的一部分。然而,随着文件数量的不断增加和文件夹命名的复杂性,我们经常面临着重命名文件夹的繁琐操作。你是否曾经因为误改文件夹名称而头疼不已?是否曾经为了找回原始名称而耗费大量时间&#…

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

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

【jitsi】jitsi 布署及docker打包

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

Word应用:一键提取手写签名

1、将带有签名的图片插入到word文档中,裁剪出签名部分; 2、点击“格式-颜色”,选择“重新着色”中的“黑白50%”; 3、“格式-颜色”,设置透明色; 4、选择“文件”选项卡,选择打开“选项”,点击“…