【C++】动态内存管理——new和delete

news2024/11/28 4:35:41

这篇文章我们讲一下C++的动态内存管理,从一个比较陌生的知识说起,我们知道,一个工程可以创建很多.c文件,我们如果定义一个全局变量,只要用extern声明一下,在每个文件都可以用。而用static修饰的全局变量只能在当前文件可用,局部的static修饰的变量只有程序走到这时才会去创建,并且只会初始化一回,比如是在一个普通函数内,就意味着如果第二次调用该函数,就不会去在初始化了。
上面所说的全局变量和static修饰的变量是存储在静态区的,我们这里所说的动态内存分配都是在堆区上的,下面说一下new和delete的基本用法,基本的形式是这样的:

int main() {
	int* p1 = new int;
	int* p2 = new int[10];
	return 0;
}

基本用法就是这样,用一个指针去接收,跟malloc是一样,但是后面会简单很多,如果就开辟一个空间的话,就直接加类型,要开辟比如十个空间就是加上方括号。那么new函数会不会初始化呢?跟malloc一样,是不会初始化的。当然我们也可以让new去初始化,就像这样:
在这里插入图片描述

单个数据初始化就用括号,多个数据就用大括号,向上面的p2情况,如果是未完全初始化,那么后面会用0给初始化,就跟数组初始化一样
在这里插入图片描述
那么想要delete也简单,直接用就行,就像这样:
在这里插入图片描述
new时用方括号了delete时就用方括号,new时不用delete时就不用
那么下面大家想一想为什么我们C++不用之前的malloc了,而是新创建了new这个操作符,对!new是一个操作符,它跟函数调用是不一样的。不只是为了简单写,还有一些其他的用处
比如说,我们有一个自定义类型,我们用malloc去创建了一个指向该类型的对象的指针,我们是很难通过这个指针去解决初始化问题的,为什么呢?首先自定义类型的成员变量是私有的,我们不能去访问,另外构造函数是程序自动调用的,我们也无法去去调用对象的构造函数,所以我说它是很难去初始化的,但也是有办法
在这里插入图片描述
但这种办法确实很鸡肋,我们这只是为了证明它可以改变。
malloc会存在这种问题,所以我们才有了new这个函数,它不仅会去开辟空间还会去调用自定义类型的构造函数
在这里插入图片描述
在这里插入图片描述
就可以这么去调用,上面是自定义类型有一个成员变量的样子,下面是有两个成员变量的样子,这就是我们上个博客写的内置类型转换。既然我们可以这么写了,那创建链表节点的时候就不用再去写相应的函数了,就可以这么去写:

struct ListNode
{
	ListNode(int val) {
		_val = val;
		_next = NULL;
	}
	int _val;
	ListNode* _next;
};

int main() {
	ListNode* n1 = new ListNode(1);
	ListNode* n2 = new ListNode(2);
	ListNode* n3 = new ListNode(3);
	return 0;
}

它直接就去自动调用构造函数了,既然new自动调用构造,那么delete就会去自动调用析构函数并且去释放空间,我们平常去析构一个比如日期类对象是没有意义的,但是当我们去建一个栈的类时调用析构就有意义了

class stack {
public:
	stack(int capacity=4) {
		 _a = new int[capacity];
		 _top = 0;
		 _capacity = capacity;
	}
	~stack() {
		delete(_a);
		_top = 0;
		_capacity = 0;
	}
private:
	int* _a;
	int _top;
	int _capacity;
};

int main() {
	stack* p = new stack;
	delete p;
	return 0;
}

这个程序呢?先是p指针指向一个栈,这个栈的12个字节是在堆区开辟的,然后会去调用堆的构造函数,又在堆上开辟4*4个字节,之后delete p时,会先去调用栈的析构函数,释放4*4个字节的空间,再去释放p指向的空间,在这里delete的作用就很明显了。
除此之外,malloc如果失败的话会去返回一个空指针,而new报错的话会抛异常,更符合C++面向对象的特性
其实我们已经知道了new的作用就是开空间和调用构造函数,那么开空间其实就用我们的malloc就可以了,只不过我们要对malloc包装一下,为了处理抛异常问题,包装完之后就变成了operator new函数,这是一个全局函数,这里的operator跟我们的运算符重载是没有关系的,只是叫这个名字而已,通过汇编我们也可以看到,new会去调用两个函数
在这里插入图片描述
我们这两个call指令就是去调用函数的意思,就是跳到对应函数的地址去执行函数,以此类推,也有一个operator delete函数,它也是去封装了free,跟new是一样的。
我们知道构造函数是不能自动调用的,但是析构函数可以,但是我们也有办法显示调用构造函数,那就是使用定位new,基本使用是这样的
在这里插入图片描述
就像第二行这样,就是这么个形式,那么显示调用有什么用处呢?比如说,我们可能有时候会频繁的小规模的开辟空间,而开辟空间这个过程是比较效率低的,这是我们就可以先申请一大块空间,叫做内存池,这就留着用,这时去内存池要空间就不用开辟但是得初始化,这时我们的显式调用构造函数就派上用场了。

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

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

相关文章

Vue Computed

小满,我的神! 视频链接 // 只读 const plusOne computed(() > count.value 1) // 可读可写 const plusOne computed({get: () > count.value 1,set: (val) > {count.value val - 1} }, { // 用于调试onTrack(e) {debugger},onTrigger(e) …

软件测试基础知识总结

之前有将基础的软件测试知识做了一个总结,但比较潦草,很多内容只是一笔带过,快到年底了,自己也有个写年终知识总结文档的计划,就将基础的理论知识重新整理一番。 有人问我,这些都是能搜索到的知识&#xf…

微信视频无法播放,快速进行格式转换方法

你是否遇到过这样的事情呢,朋友或者家人在电脑上用微信给你发的视频,在自己的微信上点开却无法播放。这种是什么原因造成的呢?是不是需要将这些无法播放的视频转换为微信支持的格式才行,那应该如何转换呢? 不要着急&a…

使用 PyWebCopy 在 Python 中克隆网页

更多资料获取 📚 个人网站:ipengtao.com PyWebCopy 是一个用于克隆网页内容的 Python 库,它允许用户从指定的 URL 复制整个网页并保存到本地。本文将介绍 PyWebCopy 的基本用法,以及如何克隆网页并保存网页内容到本地文件夹。 安…

QTableView用代码设置选中状态

背景: 个人笔记,欢迎探讨。 目的是实现用代码设置表格中的选中状态,比如选中某个单元格,或某行,某列。实际上只要能完成选中单元格,行和列都是单元格的集合,道理一样。 QTableWidget比QTable…

常用汇编指令集

寄存器 如上是OD展示的寄存器,逐条说明常用的寄存器和标志位含义: EIP:寄存器指向即将要执行的指令的地址(EIP中的地址,就是下一步要执行指令的地址) ESP:里面的内容永远指向堆栈的最顶端 EAX&…

青春挚爱-计算机

为什么选择计算机? 看到这个问题,不禁把镜头遥向十几年前的某个片刻。 一、梦想的种子 首先信仰技术是从小的梦想,比如科学家精神之启蒙,比如勇敢者探索之启蒙。 为什么课本中的科学家可以做到精忠报国,矢志不渝&…

Elasticsearch:什么是向量嵌入?

向量嵌入定义 向量嵌入 (vector embeddings) 是一种将单词、句子和其他数据转换为捕获其含义和关系的数字的方法。 它们将不同的数据类型表示为多维空间中的点,其中相似的数据点更紧密地聚集在一起。 这些数字表示可以帮助机器更有效地理解和处理这些数据。 单词和…

云原生的 CI/CD 框架tekton - Trigger(二)

上一篇为大家详细介绍了tekton - pipeline,由于里面涉及到的概念比较多,因此需要好好消化下。同样,今天在特别为大家分享下tekton - Trigger以及案例演示,希望可以给大家提供一种思路哈。 文章目录 1. Tekton Trigger2. 工作流程3…

【计算机系统基石与Linux进程管理深度解析】

​​​​​​​ 【本节重点】 认识冯诺依曼系统 操作系统概念与定位 深入理解进程概念,了解PCB 学习进程状态,学会创建进程,掌握僵尸进程和孤儿进程,及其形成原因和危害 1.冯诺依曼体系结构 我们常见的计算机,如…

App内存优化

一、内存优化介绍 1.背景介绍 内存是大问题但缺乏关注压实骆驼的最后一个稻草(堆栈溢出) 2.内存问题 内存抖动:锯齿状、GC导致卡顿内存泄露:可用内存减少、频繁GC内存溢出:OOM,程序异常 二、优化工具选…

【C语言】函数递归详解(二)

前言 在上一篇博客函数递归详解(一)中讲解了什么是递归,递归的思想及限制条件以及两个递归的例子,这一篇博客将讲解递归与迭代的关系。 递归与迭代 递归是一种很好的编程技巧,但是同很多技巧一样也是可能被误用的&…

api 网关

API网关 什么是网关? 微服务背景下,一个系统被拆分为多个服务,但是像安全认证,流量控制,日志,监控等功能是每个服务都需要的,没有网关的话,我们就需要在每个服务中单独实现&#x…

2023年【T电梯修理】考试总结及T电梯修理证考试

题库来源:安全生产模拟考试一点通公众号小程序 T电梯修理考试总结考前必练!安全生产模拟考试一点通每个月更新T电梯修理证考试题目及答案!多做几遍,其实通过T电梯修理证考试很简单。 1、【多选题】《特种设备安全法》规定&#x…

【2】PyQt创建窗口

1. 第一个PyQt窗口 from PyQt5.QtWidgets import QApplication,QWidget import sys# 1.创建应用程序 app QApplication(sys.argv)# 2.创建窗口 w QWidget()# 3.显示窗口 w.show()# 4.等待窗口停止 sys.exit(app.exec()) 执行代码,就会显示PyQt窗口: 2. PyQt模块简介 PyQt中…

基于SpringBoot的校园互助网站

简介 本系统分为三个角色,分别是普通用户和管理员、以及超级管理员,主要的功能模块有注册、登录、物品代购、快递代取、话题管理、任务管理、反馈管理、投诉管理、订单管理等功能模块。 项目 数据库 首页 登录 新增反馈 发布话题 发布任务 接单 我要投诉…

粒子群优化算法的实践

粒子群优化算法的实践 flyfish 粒子群优化算法(Particle Swarm Optimization,PSO)或者粒子群算法 红叉的地方是理想之地,这些粒子都想去,总结8个字是信息共享,个人决策。 上完图之后,上代码&a…

算法通关村——数论问题

数论是一个很重要的学科,覆盖领域极广,小到小学的智力问题,大到世界顶级科学家都一直在研究相关问题,因此其难度跨度非常大。在程序设计里 ,也经常会出现数论的问题,但是,这些一般都是比较基本的…

训练自己的YOLOv8姿态估计模型

在不断发展的计算机视觉领域,姿态估计作为一项关键创新脱颖而出,改变了我们理解视觉数据以及与视觉数据交互的方式。 Ultralytics YOLOv8 处于这一转变的最前沿,提供了一个强大的工具来捕捉图像中物体方向和运动的微妙之处。 NSDT工具推荐&am…

Avalonia开发之HelloWrold

前言 本文所有讲解是以VS2022为开发工具,官方提供了VS2022和2019的扩展支持,大家根据自己的是实际情况下载相应的扩展进行安装。 安装扩展 如下图,我们在扩展菜单里面找到扩展管理,如下图: 在扩展管理的搜索栏里面…