C++程序设计——动态内存管理

news2024/9/21 8:00:28

一、C/C++内存分布

1.栈(堆栈)

        存储非静态局部变量、函数参数、返回值等等,栈是向下增长。

2.内存映射段

        是高效的I/O映射方式,用于转载一个共享的动态内存库。用户可使用系统接口创建共享内存,做进程间通信。

3.堆

        用于程序运行时动态内层分配,堆是向上增长。

4.数据段

        存储全局数据和静态数据。

5.代码段

        存储可执行的代码、只读常量。

二、C++内存管理

1.new/delete

        C语言内存管理方式在C++中也可以使用,但是在某些情况下就不太方便使用或使用起来比较麻烦,因此C++提供了自己的内存管理方式:通过new和delete操作符来进行动态内存管理。

注意:

(1)new和delete不是函数,是C++提供的关键字。

(2)new是申请空间,默认是在堆上申请。

(3)delete是释放空间,

2.new/delete操作内置类型

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

注意:

malloc(size):

        只是从堆上申请size个字节的空间,并不会对空间中的内容进行初始化,即不会调用构造函数

free(p):

        只是将p所指向的堆空间释放,并不会调用析构函数对空间中的内容进行清理,即不会调用析构函数

new:

        除了会申请空间外,还会调用构造函数对空间中的内容进行初始化。

delete:

        除了会释放对象空间外,还会调用析构函数对空间中的资源进行清理。

三、new和delete的实现原理

1.内置类型

        对于内置类型,new和malloc,delete和free基本类似。不同的是,new和delete针对的是单个元素的空间,new[]和delete[]针对的是连续空间;new在申请空间失败时会抛异常,而malloc会返回NULL。

2.自定义类型

new的原理:

(1)调用operator new函数,申请空间。

(2)在申请的空间上执行构造函数,完成对象的构造。

delete的原理:

(1)在空间上执行析构函数,完成对象中资源的清理。

(2)调用operator delete函数释放对象的空间。

new T[N]的原理:

(1)调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请。

(2)在申请的空间上执行N次构造函数。

delete[]的原理:

(1)在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理。

(2)调用operator delete[]释放空间,在operator delete[]中实际调用operator delete来释放空间。

四、operator new和operator delete函数

1.概念

new和delete:

        是用户进行动态内存申请和释放的操作符。

operator new 和operator delete:

        是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。

2.函数实现

operator new:

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
			// throw a bad_alloc exception
			static const std::bad_alloc nomem;
			_RAISE(nomem);
		}
	return (p);
}

operator delete:

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;
}

注意:

        通过这两个全局函数的实现可以看出,operator new实际也是通过malloc来申请空间,若申请成功则直接返回,否则执行用户提供的空间不足对应措施,如果用户提供了对应措施则继续申请,否则就抛异常。

        operator delete最终也是通过free来释放空间。

五、定位new表达式

1.概念

        定位new表达式是指在已经分配的原始内存空间中调用构造函数初始化一个对象。

2.使用格式

new(place_address) type

或new(place_address) type(initializer-list)

注意:

        place_address必须是一个指针;

        initializer-list是类型的初始化列表。

3.使用场景

        定位new表达式在实际中一般是配合内存池使用,因为内存池分配处的内存没有初始化,若是自定义类型的对象,需要使用new的定义表达式进行显示调用构造函数进行初始化。

六、malloc/free和new/delete的区别

共同点:

        malloc/free和new/delete都是从堆上申请空间,并且需要用户主动释放。

区别:

(1)malloc和free是函数,而new和delete是操作符。

(2)malloc申请的空间不会初始化,而new可以进行初始化。

(3)malloc申请空间时,需要手动计算空间大小,而new只需要在其后跟上空间类型即可。

(4)malloc的返回值为void*,需要手动进行强转,而new不需要。

(5)malloc申请空间失败时,返回NULL因此需要判空,而new是抛异常,不需要判空,但是需要捕获异常。

(6)申请自定义类型对象空间时,malloc/free只会开辟和释放空间,不会调用构造函数和析构函数,而new在开辟空间后会调用构造函数进行初始化,delete在释放空间前,会调用析构函数进行对象内部的资源清理。

七、内存泄漏

1.什么是内存泄漏

        内存泄漏是指因为疏忽或错误导致程序未能释放已经不再使用的内存的情况。内存泄漏并不是指内存在物理意义上的消失,而是应用程序在分配某段内存后,因为设计错误,失去了对该段内存的控制,从而造成了内存浪费。

2.内存泄漏的危害

        长期运行的程序出现内存泄漏,会造成较大的影响,比如操作系统、服务器等,出现内存泄漏会导致响应越来越慢,最终程序卡死等情况。

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

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

相关文章

WPS的简单JS宏应用

有一阵子没写博客了,各种琐事忙碌;前段时间接触了下WPS的宏功能,抽点时间写个学习笔记吧。 案例背景简单说一下,主任让我统计OA后台在建工程项目的概况,后台数据导出一张表,再问隔壁经营部的同事要了一张中…

java类的初始化2023018

类的初始化: 第一次使用某个类,例如Person类,系统通常会在第一次使用Person类时加载这个类并初始化这个类。在类的准备阶段,系统将会为该类的类变量分配内存空间,并指定默认初始值。当Person类初始化完成后&#xff0c…

机器学习笔记之深度玻尔兹曼机(二)深度玻尔兹曼机的预训练过程

机器学习笔记之深度玻尔兹曼机——深度玻尔兹曼机的预训练过程引言深度信念网络预训练过程的问题深度玻尔兹曼机的预训练过程(2023/1/24)引言 上一节介绍了玻尔兹曼机系列的相关模型,本节将介绍深度玻尔兹曼机的预训练过程。 深度信念网络预训练过程的问题 在玻尔…

Escher 愛雪磁磚設計法則 - 高雄燕巢深水國小科展指導

“Talk is cheap. Show me the code.” ― Linus Torvalds 老子第41章 上德若谷 大白若辱 大方無隅 大器晚成 大音希聲 大象無形 道隱無名 拳打千遍, 身法自然 “There’s no shortage of remarkable ideas, what’s missing is the will to execute them.” – Seth Godin …

GreenPlum AOCO列存如何将数据刷写磁盘

GreenPlum AOCO列存如何将数据刷写磁盘AOCO列存表每个字段一个文件,前面我们介绍了列存表如何加载数据页,本文我们重点介绍AOCO表如何进行刷写。AOCO表进行insert、update、delete会产生脏数据,和heap表的异步脏页刷写不同,AOCO表…

写一个锅炉温控系统用python编写

简单来说就是锅炉水热了之后循环泵自动开启,然后将热水输送走,送到暖气,热水抽走,凉水进入锅炉,温度降低,循环泵关闭,等待下一次水烧热。因为需要取暖的房子距离烧锅炉的地方比较远,所以需要循环泵,如果距离近的话水烧热后利用热水上流冷水回流的原理会自动完成循环。…

前言技术之mybatis-plus

目录 1.什么是mybatis-plus 2.初体验 3.日志 4.主键生成策略 5.更新 6.自动填充 1.什么是mybatis-plus 升级版的mybatis,目的是让mybatis更易于使用, 用官方的话说“为简化而生” 官网: MyBatis-Plus 2.初体验 1.准备数据库脚本 数据…

BI 解决方案:BimlStudio 22.3.0 Crack

全功能开发环境:::: 导入现有解决方案 通过添加 BimlScript 自动化进行更改并重新生成包;使您的解决方案更好、更快。 可视化整个 BI 解决方案 通过我们的可视化设计器在一个位置进行更改,观察您的整个解决方案自行更新…

【ArcGIS微课1000例】0061:ArcGIS打开xyz格式点云数据的方法

本文讲述ArcMap和ArcScene中如何打开xyz格式的点云数据并做可视化的方法。 文章目录 一、xyz格式点云简介二、ArcMap打开xyz点云三、ArcScene打开xyz点云四、注意事项一、xyz格式点云简介 本实验使用的数据是配套数据包中的0061.rar,斯坦福大学的点云数据,格式为X,Y,Z,如下…

【My Electronic Notes系列——晶闸管】

目录 序言: 🏮🏮新年的钟声响,新年的脚步迈,祝新年的钟声,敲响你心中快乐的音符,幸运与平安,如春天的脚步紧紧相随,春节快乐!春华秋实,我永远与你…

Linux下动静态库的打包与使用C C++

目录前言为什么用动静态库动态链接与静态链接底层优缺点Linux下的动静态库动静态库的对比打包静态库使用静态库打包动态库使用动态库小结win下打包动静态库前言 为什么用动静态库 我们在实际开发中,经常要使用别人已经实现好的功能,这是为了开发效率和…

移动窗口下的LiDAR点云区域生长滤波算法教程

一、前言LiDAR 滤波的现有方法包括:数学形态学滤波法、基于地形坡度滤波、最小二乘内插法滤波等滤波方法。最小二乘内插法能够较好的获取地形趋势面,但是算法中无法根据地形自适应设置参数;在地形起伏较大的地区提取结果精度低;无…

Linux进程的后台运行

文章目录一. 什么是进程?二. 进程后台运行在了解三种进程后台运行的方式前,小编觉得有必要先简单讲解一下什么是进程。 PS: 本篇博客技术参考价值不大,只是类似随笔比较水,详细的知识点可以关注一下nohup命令的使用。 一. 什么是进程? 什…

00开篇词:带你玩转gRPC框架

前言 大家好,先做一下自我介绍 我叫Barry Yan,目前是一名互联网公司的研发工程师,同时也是后端技术领域的狂热爱好者和技术博主,在GitHub、CSDN社区、51CTO博客社区、阿里云技术社区、掘金技术社区和InfoQ写作社区等都有自己的博…

详解1242:网线主管(二分答案经典习题)

题目1242:网线主管时间限制: 1000 ms 内存限制: 65536 KB提交数: 23180 通过数: 5566【题目描述】仙境的居民们决定举办一场程序设计区域赛。裁判委员会完全由自愿组成,他们承诺要组织一次史上最公正的比赛。他们决定将选手的电脑用星形拓扑结构连接在一…

【SVM原理推导】核SVM为什么能分类非线性问题?

核SVM为什么能分类非线性问题?要解决这个问题,首先应该先深入理解SVM的原理与本质。(涉及SVM的问题是很常见的,因为SVM可以算是传统机器学习领域非常成功的算法之一了,现在仍有许多research运用SVM解决问题。) 一、支持向量机(SVM) 1. 基本介绍与提出背景 支持向量机…

【C++】lambda 表达式 | 包装器

​🌠 作者:阿亮joy. 🎆专栏:《吃透西嘎嘎》 🎇 座右铭:每个优秀的人都有一段沉默的时光,那段时光是付出了很多努力却得不到结果的日子,我们把它叫做扎根 目录👉lambda表…

解决宏碁非凡S3 安装Win11时无法找到驱动器问题

1 问题描述 机型:宏碁非凡S3 2022款CPU:i5 1240P安装系统:Win11 专业版问题描述:安装系统时,在选择驱动器界面无法找到驱动器,如下图所示 2 解决流程 查了一下网上的解决办法,进入BIOS把VMD C…

非极大值抑制(Non-Maximum Suppression)

文章目录一、什么是非极大值抑制二、为什么要用非极大值抑制三、 如何使用非极大值抑制四、代码段一、什么是非极大值抑制 非极大值抑制,简称为NMS算法,英文为Non-Maximum Suppression。其思想是搜素局部最大值,抑制非极大值。NMS算法在不同…

JavaEE7-Bean的作用域

目录 1.作用域定义 2.Bean的6种作用域 2.1.singleton:单例作用域(默认作用域) 2.2.prototype:原型作用域(多例作用域) 2.3.request:请求作用域 2.4.session:会话作用域 2.5.a…