【C++】内存管理方式--new/delete

在这里插入图片描述

💐 🌸 🌷 🍀 🌹 🌻 🌺 🍁 🍃 🍂 🌿 🍄🍝 🍛 🍤
📃个人主页 :阿然成长日记 👈点击可跳转
📆 个人专栏: 🔹数据结构与算法🔹C语言进阶🔹C++
🚩 不能则学,不知则问,耻于问人,决无长进
🍭 🍯 🍎 🍏 🍊 🍋 🍒 🍇 🍉 🍓 🍑 🍈 🍌 🍐 🍍

文章目录

  • 一、C语言中的内存管理方式
  • 二、C++中的内存管理方式
    • 1、new/delete操作内置类型
    • 2.new/delete操作自定义类型
  • 三、🔆operator new与operator delete函数(重点)
    • 1.通过反汇编看底层
    • 2.透过源码分析两个全局函数
      • 1)==operetor new==
      • 2)==operetor delete==
  • 四、🚩再次理解new/delete
    • 1.new的原理
    • 2.delete的原理

一、C语言中的内存管理方式

在C语言中,内存的管理方式 有【malloc 、calloc、realloc】这几种动态开辟内存的方式。
那你还记得他们的区别吗?

  • malloc用于分配指定大小的未初始化内存块,其不会对申请出来的内存块做初始化工作
    calloc用于分配指定数量和大小的连续内存块,并将其初始化为0
    realloc用于重新分配内存块的大小,并尽可能保留原有数据。其有两种扩容机制,分别为【本地扩容】和【异地扩容】

二、C++中的内存管理方式

C语言内存管理方式在C++中可以继续使用,但有些地方就无能为力,而且使用起来比较麻烦,因此C++又提出了自己的内存管理方式:通过new和delete操作符进行动态内存管理。

1、new/delete操作内置类型

  • 接下去就让我们来看在C++中如何使用new这个关键字来动态申请空间

1). 动态申请一个int类型的空间

  int* p1 = new int;

2).动态申请一个int类型的空间并初始化为10

int* p2 = new int(10);

3).动态申请10个int类型的空间

 int* p3 = new int[3];
  • 那既然申请了,我们就要去释放这些空间,C语言中使用free,但是在C++中呢,我们使用delete,对于普通的空间我们直接delete即可,但是对于数组来说,我们要使用delete[]
  delete p1;
  delete p2;
  delete[] p3;

进行调试可以发现:

  • 对于单块的内存区域,只需要使用new 数据类型(初始化数值)的方式即可;而对于像数组这样的空间,我们要使用new int[5]{初始化数值}的形式去进行,此时才可以做到一个初始化
    在这里插入图片描述

2.new/delete操作自定义类型

学习完了使用new/delete去操作C++中的内置类型,接下去我们来看看我们要如何去操作一个自定义类型

通过下面一个例子,你就会知道C++中的new,delete用起来有多爽了。🐶

  • 在之前C语言中学习链表时我们新建结点。由于使用malloc函数,每次新建结点需要进行调用,安全检查等等操作。

对比1:

struct ListNode {
	int val;
	struct ListNode* next;
};

struct ListNode* BuyListNode(int x)
{
	struct ListNode* node = (struct ListNode*)malloc(sizeof(struct ListNode));
	if (NULL == node)
	{
		perror("fail malloc");
		exit(-1);
	}
	node->val = x;
	node->next = NULL;

	return node;
}

struct ListNode* n1 = BuyListNode(1);
struct ListNode* n2 = BuyListNode(2);
struct ListNode* n3 = BuyListNode(3);

  • 使用new/delete:并且使用之前所学习过的构造函数初始化列表在开辟出空间的时候就做一个初始化的工作

对比2:

struct ListNode {
	int val;
	struct ListNode* next;
	ListNode(int x)
		: val(x)
		, next(NULL)
	{}
};
ListNode* n4 = new ListNode(1);
ListNode* n5 = new ListNode(2);
ListNode* n6 = new ListNode(3);
  • cv对比1,2就可以很明显的发现,使用new减少了不少代码量,而且还提升了安全性。

在这里插入图片描述

  • 📋通过上面的调试,我们可以知道在C++中使用new是会去自动调用构造函数并完成初始化的。
  • 📋而且,new几个对象,就会调用几次构造函数,delete 也一样。
  • 注意点:malloc出来的一定要用free,而new出来的一定要用delete

三、🔆operator new与operator delete函数(重点)

1.通过反汇编看底层

new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过 operator delete全局函数来释放空间。

通过反汇编,可以清楚的看出new 的底层还是调用了operator new函数。所以我们想要弄清楚new的原理,就需要搞明白operator new 函数。

  • 这里我们需要关注的点有两个,即这两个call指令的调用,分别是调用【operator new】从堆区去开空间和调用【A::A】这个构造函数去进行初始化工作
    在这里插入图片描述
    这里我们需要关注的点也有两个,即这两个call指令的调用,分别是调用【A::~A】去析构函数释放资源和调用【operator delete】这个函数去释放从堆区申请的空间。不过呢,它们这两个部分被编译器做了一个封装,在外层我们还需用通过一个call指令和jmp指令去做一个跳转,才能看到底层的这块实现

在这里插入图片描述

2.透过源码分析两个全局函数

1)operetor new

  • 通过查看它的源代码我们可以发现其内部还是使用【malloc】去堆中申请空间的
void* __CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{
	// try to allocate size bytes
	void* p;
	while ((p = malloc(size)) == 0)
	{
		if (_callnewh(size) == 0)
		{
			// report no memory
			// 如果申请内存失败了,这里会抛出bad_alloc 类型异常
			static const std::bad_alloc nomem;
			_RAISE(nomem);
		}
	}
	return (p);
}

2)operetor delete

接下去的话是是operator delete,仔细去观察的话可以看出这段代码有调用到一个_free_dbg()这个函数,它其实就是我们在C语言中所写的free()函数,那么就可以得出其实这个函数底层也和operator delete类似是调用了【free】来进行释放空间的

void operator delete(void* pUserData)
{
	_CrtMemBlockHeader* pHead;
	RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));

	if (pUserData == NULL)
		return;

	_mlock(_HEAP_LOCK);  /* block other threads */
	__TRY
		/* get a pointer to memory block header */
		pHead = pHdr(pUserData);
	    /* verify block type */
		_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
		_free_dbg(pUserData, pHead->nBlockUse);

	__FINALLY
		_munlock(_HEAP_LOCK);  /* release other threads */
	__END_TRY_FINALLY
	return;
}

四、🚩再次理解new/delete

1.new的原理

  • 1.调用operator new函数申请空间
    2.在申请的空间上执行构造函数,完成对象的构造

2.delete的原理

  • 1.在空间上执行析构函数,完成对象中资源的清理工作
    2.调用operator delete函数释放对象的空间

下面这幅图很好解释了他们之间的关系
在这里插入图片描述

📜补充:使用new/delete发生异常时,会进行抛出异常。
在这里插入图片描述

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

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

相关文章

Repo命令使用实例(三十八)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…

(01)Hive的相关概念——架构、数据存储、读写文件机制

目录 一、架构及组件介绍 1.1 Hive整体架构 1.2 Hive组件 1.3 Hive数据模型(Data Model) 1.3.1 Databases 1.3.2 Tables 1.3.3 Partitions 1.3.4 Buckets 二、Hive读写文件机制 2.1 SerDe 作用 2.2 Hive读写文件流程 2.2.1 读取文件的过程 …

BUGKU-WEB 你必须让他停下

题目描述 题目截图如下: 进入场景看看: 解题思路 图片会消失,那应该是使用了js来控制根据提示,那就是要停止js才会看到flag (也就是要抓包,不要陷入停止js的思维) 相关工具 F12大法Burp Suit抓包工具 解题步骤 出现图片的时候,源码中确实出现…

ICLR 2023#Learning to Compose Soft Prompts for Compositional Zero-Shot Learning

组合零样本学习(CZSL)中Soft Prompt相关工作汇总(一) 文章目录 组合零样本学习(CZSL)中Soft Prompt相关工作汇总(一)ICLR 2023#Learning to Compose Soft Prompts for Compositional…

Android之Android.bp文件格式语法(一百八十六)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…

力扣hot3--并查集+哈希

第一想法是排个序然后遍历一遍,but时间复杂度就超啦 并查集居然与哈希结合了() 已经好久没用过并查集了,,,我们用哈希表f_node中来记录原结点的父节点,其中key是原结点,value是父节点…

Github项目推荐-Tiny-Rdm

项目地址 GitHub - tiny-craft/tiny-rdm: A Modern Redis GUI Client 项目简述 一个开源的Redis管理工具,有漂亮的界面和丰富的功能。使用的编程语言如下 项目截图

【Qt】环境安装与初识

目录 一、Qt背景介绍 二、搭建Qt开发环境 三、新建工程 四、Qt中的命名规范 五、Qt Creator中的快捷键 六、QWidget基础项目文件详解 6.1 .pro文件解析 6.2 widget.h文件解析 6.3 widget.cpp文件解析 6.4 widget.ui文件解析 6.5 main.cpp文件解析 七、对象树 八、…

对什么都不感兴趣,怎么办?

这大概是现代社会,最为常见的都市病。 很多人大抵都明白:好的生活是什么样的呢?要有一个大目标,再分拆成一个个小目标,每天朝着目标前进,看着自己的进步和成长,转化为成就感和动力 —— 对不对&…

揭秘Angular世界的奥秘:全面提升你的前端开发技能!

介绍:Angular是一个由Google维护的开源JavaScript框架,专为构建Web应用程序而设计,特别适合开发大型单页应用(SPA)。以下是对Angular的详细介绍: 技术栈:Angular使用HTML作为模板语言&#xff0…

C++集群聊天服务器 nginx+redis安装 笔记 (中)

一、nginx安装 nginx: download 下载nginx安装包 hehedalinux:~/package$ tar -zvxf nginx-1.24.0.tar.gz nginx-1.24.0/ nginx-1.24.0/auto/ nginx-1.24.0/conf/ nginx-1.24.0/contrib/ nginx-1.24.0/src/ nginx-1.24.0/configure nginx-1.24.0/LICENSE nginx-1.24.0/README…

言语残疾和言语残疾分级

言语残疾和言语残疾分级 言语残疾,指各种原因导致的不同程度的言语障碍,经治疗一年以上不愈或病程超过两年,而不能或难以进行正常的言语交流活动,以致影响其日常生活和社会参与。包括:失语、运动性构音障碍、器质性构音…

黑马程序员——移动Web——day02

目录 空间转换 空间转换简介平移视距旋转左手法则rotate3d-了解立体呈现案例-3d导航缩放动画 动画实现步骤animation复合属性animation拆分写法案例-走马灯精灵动画多组动画综合案例-全名出游 背景云彩位置和动画文字动画 1.空间转换 空间转换简介 空间:是从坐标…

ITK 图像分割(一):阈值ThresholdImageFilter

效果: Video: 区域增加分割 1、itkThresholdImageFilter 该类的主要功能是通过设置低阈值、高阈值或介于高低阈值之间,则将图像值输出为用户指定的值。 如果图像值低于、高于或介于设置的阈值之间,该类就将图像值设置为用户指定的“外部”值…

山西电力市场日前价格预测【2024-02-10】

日前价格预测 预测说明: 如上图所示,预测明日(2024-02-10)山西电力市场全天平均日前电价为126.73元/MWh。其中,最高日前电价为302.95元/MWh,预计出现在08:15。最低日前电价为0.00元/MWh,预计出…

Stable Diffusion之最全详解图解

Stable Diffusion之最全详解图解 1. Stable Diffusion介绍1.1 研究背景1.2 学术名词 2.Stable Diffusion原理解析2.1 技术架构2.2 原理介绍扩散过程 3.1 Diffusion前向过程3.2 Diffusion逆向(推断)过程 1. Stable Diffusion介绍 Stable Diffusion是2022…

分布式文件系统 SpringBoot+FastDFS+Vue.js【一】

分布式文件系统 SpringBootFastDFSVue.js【一】 一、分布式文件系统1.1.文件系统1.2.什么是分布式文件系统1.3.分布式文件系统的出现1.3.主流的分布式文件系统1.4.分布式文件服务提供商1.4.1.阿里OSS1.4.2.七牛云存储1.4.3.百度云存储 二、fastDFS2.1.fastDSF介绍2.2.为什么要使…

跟着pink老师前端入门教程-day26

一、计算机编程基础 (一)编程语言 1、编程 编程:就是让计算机为解决某个问题而使用某种程序设计语言编写程序代码,并最终得到结果的过程。 计算机程序:就是计算机所执行的一系列的指令集合,而程序全部…

MySQL 基础知识(三)之数据库操作

目录 1 显示当前时间、用户名、数据库版本 2 查看已有数据库 3 创建数据库 4 使用数据库 5 查看当前使用的数据库 6 查看当前数据库信息 7 查看数据库编码 8 修改数据库信息 9 删除数据库 10 查看最大连接数 11 查看数据库当前连接数,并发数 12 查看数据…

2022年12月电子学会青少年软件编程 中小学生Python编程等级考试二级真题解析(判断题)

2022年12月Python编程等级考试二级真题解析 判断题(共10题,每题2分,共20分) 26、字典的元素可以通过键来访问,也可以通过索引(下标)来访问 答案:错 考点分析:考查字典相关知识,字…