C++ -5- 内存管理

news2024/11/25 7:15:46

文章目录

  • C语言和C++内存管理的区别示例
  • 1. C/C++ 中程序内存区域划分
  • 2. C++中动态内存管理
  • 3.operator new 与 operator delete 函数
  • 4.new 和 delete 的实现原理
  • 5.定位new表达式

C语言和C++内存管理的区别示例

在这里插入图片描述

//C语言:
struct SListNode
{
	int data;
	struct SListNode* next;
};
// 动态申请一个节点
struct SListNode* BuySListNode(int x)
{
	struct SListNode* newSList = (int*)malloc(sizeof(struct SListNode));
	if (!newSList)
	{
		perror("BuySListNode()");
		exit(-1);
	}
	newSList->data = x;
	newSList->next = NULL;
	return newSList;
}

//C++:
class SListNode
{
	int data;
	struct SListNode* next;
};
//申请空间:
SListNode* p = new SListNode;

1. C/C++ 中程序内存区域划分

为什么需要内存管理?——需要对不同的数据分而治之。

  1. 又叫堆栈–非静态局部变量/函数参数/返回值等等,栈是向下增长的。
  2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口
    创建共享共享内存,做进程间通信。(了解)
  3. 用于程序运行时动态内存分配,堆是可以上增长的。
  4. 数据段--存储全局数据和静态数据。
  5. 代码段–可执行的代码/只读常量。

2. C++中动态内存管理

通过 new 和 delete 操作符进行动态内存管理。

  1. 使用 new 不用检查,如果申请失败会直接抛异常。
  2. 在申请自定义类型的空间时,new会调用构造函数,delete会调用析构函数,而malloc与
    free不会。
    在这里插入图片描述

3.operator new 与 operator delete 函数

→ 本质上是 mallocfree 的封装

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

operator new 实际也是通过malloc来申请空间,如果malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就 抛异常operator delete 最终是通过free来释放空间的。


4.new 和 delete 的实现原理

  • 内置类型
    如果申请的是内置类型的空间,new和malloc,delete和free基本类似,不同的地方是:
    new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛异常,malloc会返回NULL。

  • 自定义类型

    • 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来释放空间

关于delete[]的补充:有些编译器为了知道需要调用几次析构函数,会在申请的空间前面多申请4个字节的空间,因此,如果直接delete会报错是因为——释放的地址不对
在这里插入图片描述

sum.new和delete 最好匹配使用,不要和malloc、free混搭


5.定位new表达式

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

  • 使用格式:new (place_address) type或者new (place_address) type(initializer-list)
    place_address必须是一个指针,initializer-list是类型的初始化列表
  • 使用场景:
    定位new表达式在实际中一般是配合内存池(就像用于蓄水的蓄水池,内存池的空间仍来自堆区,通过内存池可以提高效率,如果内存池的空间不够,仍会向堆区申请空间)使用。
    因为内存池分配出的内存没有初始化,所以如果是自定义类型的对象,需要使用new的定义表达式进行显示调构造函数进行初始化。

示例:

class A
{
public:
	A(int a = 0)
		: _a(a)
	{
		cout << "A():" << this << endl;
	}
	~A()
	{
		cout << "~A():" << this << endl;
	}
private:
	int _a;
};

// 定位new/replacement new
int main()
{
	// p1现在指向的只不过是与A对象相同大小的一段空间,还不能算是一个对象,因为构造函数没有执行
	A* p1 = (A*)malloc(sizeof(A));
	new(p1)A;  // 注意:如果A类的构造函数有参数时,此处需要传参
	p1->~A();
	free(p1);

	A* p2 = (A*)operator new(sizeof(A));
	new(p2)A(10);
	p2->~A();
	operator delete(p2);
	return 0;
}

END

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

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

相关文章

什么是内存?什么是内存逃逸?怎么做内存逃逸分析

内存 平时我们在电脑上听歌&#xff0c;聊天&#xff0c;或者启动某个程序&#xff0c;那么这个启动过程&#xff0c;其实就是把程序从硬盘读入到内存中去。就像安卓手机&#xff0c;内存不够了很卡&#xff0c;杀掉几个软件&#xff0c;内存就升上来了。但也不是所有的程序都…

产品经理需要了解api接口的哪些东西

一、作为产品经理&#xff0c;需要了解API接口的以下方面&#xff1a; 功能&#xff1a;API接口的功能是指它提供的业务功能&#xff0c;包括数据查询、修改、增加、删除、计算等等&#xff0c;根据产品的需求确定需要调用哪些API接口。请求方式和传参&#xff1a;API接口的请…

致力提供一站式数据可视化解决方案,支持报表、图表、大屏

一、开源项目简介 Davinci是一个DVAAS&#xff08;Data Visualization as a Service&#xff09;平台解决方案。 Davinci面向业务人员/数据工程师/数据分析师/数据科学家&#xff0c;致力于提供一站式数据可视化解决方案。既可作为公有云/私有云独立使用&#xff0c;也可作为…

Linux进程通信:信号

1. 信号的概念 Linux进程间通信的方式之一。信号也称为“软件中断”。 信号特点&#xff1a; 简单&#xff1b;携带信息有限&#xff1b;满足特定条件才发送信号&#xff1b;可进行用户空间和内核空间进程的交互&#xff1b; 2. 信号的编号 kill -l // 查看信号编号 POS…

ModelArts的使用

完整流程第一个实例&#xff1a;AI初学者&#xff1a;使用订阅算法构建模型实现花卉识别_AI开发平台ModelArts_最佳实践_模型训练&#xff08;预置算法-新版训练&#xff09;_华为云 一、支持的模型 可以在gitee上下载标准网络模型&#xff1a; models: Models of MindSpore …

Prometheus优化及高可用

Prometheus优化及高可用 概述 Prometheus几乎已成为监控领域的事实标准&#xff0c;它自带高效的时序数据库存储&#xff0c;可以让单台 Prometheus 能够高效的处理大量的数据&#xff0c;还有友好并且强大的 PromQL 语法&#xff0c;可以用来灵活的查询各种监控数据以及配置…

使用 chat_flutter 进行聊天记录展示

前言 最近需要实现一个聊天记录的页面展示&#xff0c;在网上发现没有适合自己的&#xff0c;于是自己就造了一个&#xff0c;总体感觉还不赖。 下面奉上地址、效果图和教程。 效果图 地址 github: https://github.com/xiaorui-23/chat_fluttergitee: https://gitee.com/xi…

搭建微型服务器(node express框架)

目录 一&#xff1a;打包&#xff08;npm run build&#xff09; 二&#xff1a;变成合法的包&#xff08;新建server文件夹&#xff09; 三&#xff1a;一路回车 四&#xff1a;新建服务器主文件 五&#xff1a;编辑server.js 六&#xff1a;node server启动服务器 七&a…

第十二章 享元模式

文章目录 前言一、享元模式基本介绍二、享元模式解决网站展现项目完整代码WebSite 抽象网站类User 外部状态用户内部状态网站 ConcreteWebSite网站工厂产生网站和负责共享&#xff08;池&#xff09; WebSiteFactoryClint 测试 三、享元模式在JDK-Interger的应用源码分析四、享…

NFS部署

共享/webdata/目录&#xff1b; ~ 用于存储 AppSrv 主机的 WEB 数据&#xff1b; ~ 仅允许 AppSrv 主机访问该共享&#xff1b; ~ 考虑安全&#xff0c;不论登入 NFS 的使用者身份为何&#xff0c;都将其设置为匿名用 户访问 StorageSrv和AppSrv nfs共享 1.安装nfs(App…

pdf怎么删除其中一页?

pdf怎么删除其中一页&#xff1f;大家都应该知道&#xff0c;PDF是一种实用性非常强且非常便携文件格式&#xff0c;许多用户对其非常熟悉。不管是工作还是学习中&#xff0c;都会下载或者使用到pdf文件。pdf文件具有非常好的兼容性&#xff0c;F可以将各种图片、文字内容整合在…

根据cadence设计图学习硬件知识day05 了解一些芯片

1.NXS0102DC &#xff08;2位双电源转换收发器&#xff09; 1.NXS0102DC 介绍 NXS0102是一款2位双电源转换收发器&#xff0c;具有自动方向感测功能&#xff0c;可实现双向电压电平转换。它具有两个2位输入输出端口&#xff08;An和Bn&#xff09;、一个输出使能输入&#xf…

Transformer 原理及代码详细解析

Transformer 原理及代码详细解析 文章目录 Transformer 原理及代码详细解析一、Transformer 背景介绍1.1 Transformer 的诞生1.2 Transformer 的优势1.3 Transformer 的市场 二、Transformer架构解析2.1 认识 Transformer 架构2.1.1 Transformer模型的作用2.1.2 Transformer 总…

k8s优雅终止pod

k8s优雅终止pod 概述 Pod 销毁时&#xff0c;会停止容器内的进程&#xff0c;通常在停止的过程中我们需要执行一些善后逻辑&#xff0c;比如等待存量请求处理完以避免连接中断&#xff0c;或通知相关依赖进行清理等&#xff0c;从而实现优雅终止目的。本文介绍在 Kubernetes …

深度学习—入门

深度学习与机器学习的区别 深度学习由机器学习中的神经网络发展而来&#xff0c;机器学习多用于处理数值数据&#xff0c;而深度学习还可处理图片、音频等数据。 特征提取方面 机器学习的特征工程步骤需要靠手动完成&#xff0c;需要大量专业领域知识。深度学习通常由多个层组…

Mysql8.0 包学包会!一篇文章解决Mysql

基于尚硅谷的Mysql8.0视频&#xff0c;修修改改。提取了一些精炼的内容。 首先需要在数据库内引入一张表。链接地址如下。 链接&#xff1a;https://pan.baidu.com/s/1DD83on3J1a2INI7vrqPe4A 提取码&#xff1a;68jy 会进行持续更新。。 1. Mysql目录结构 Mysql的目录结构…

传感器-红外接收,NodeMCU,arduino实现红外接收,4.x版本的irRemote库的使用

一&#xff0c;常见视频和搜索到接收红外的代码 发送参考&#xff0c;接收参考 这里只是看arduino中的接收程序&#xff0c; #include <IRremote.h> int RECV_PIN 5; /红外接收模块的s引脚 IRrecv irrecv(RECV_PIN); decode_results results; void setup() {Serial.b…

复现Apache HTTPD 换行解析漏洞(CVE-2017-15715)

影响版本 2.4.0~2.4.29都有可能存在该漏洞 原理分析 进入容器 docker exec -it 容器ID /bin/bash 该程序是采用黑名单的形式&#xff0c;如果文件后缀名不在名单内即可上传&#xff0c;所以 a.php\x0A不在黑名单列表中&#xff0c;可以上传。但是x0A是换行符&#xff0c;所…

Cahpter 3 : Defining Clocks(ug903:Vivado using constraints

1、About Clocks 在数字设计中&#xff0c;时钟代表了从寄存器到寄存器可靠传输数据的时间基准。XilinxVivado集成设计环境&#xff08;IDE&#xff09;时序引擎使用时钟特性来计算时序路径要求&#xff0c;并通过松弛计算报告设计时序裕度。必须正确定义时钟&#xff…

本原数据:回归数据库技术本原,做难而正确的事

数据库技术是信息科技领域的最为重要的技术之一。随着科技的不断进步&#xff0c;数据库技术得到了迅速的发展&#xff0c;应用范围也越来越广泛。 与此同时&#xff0c;在数据量持续高速增长的情况下&#xff0c;企业对数据库也提出了更高的要求&#xff0c;例如数据存储越来…