C++内存管理详解

news2025/1/25 9:05:06

大家好,这里是bang_bang,今天来分享下内存管理的知识。


目录

1.C/C++内存分布

2.C++内存管理方式

  2.1new/delete操作内置类型

  2.2new/delete操作自定义类型

3.operator new与operator delete函数

  3.1operator new

  3.2operator delete

4.new和delete的实现原理

  4.1内置类型

  4.2自定义类型


1.C/C++内存分布

        首先我们要想了解内存管理,就要了解内存划分的区域都是什么。

内存划分5个区域:代码区,常量区,静态区,堆区,栈区。

        这里推荐一个大佬的文章:https://blog.csdn.net/u014470361/article/details/79297601

 来我们来举个🌰:

分析下各变量存储位置。

int globalVar = 1;
static int staticGlobalVar = 1;
void Test()
{
	static int staticVar = 1;
	int localVar = 1;
	int num1[10] = { 1, 2, 3, 4 };
	char char2[] = "abcd";
	const char* pChar3 = "abcd";
	int* ptr1 = (int*)malloc(sizeof(int) * 4);
	int* ptr2 = (int*)calloc(4, sizeof(int));
	int* ptr3 = (int*)realloc(ptr2, sizeof(int) * 4);
	free(ptr1);
	free(ptr3);
}
选项: A.栈  B.堆  C.数据段(静态区)  D.代码段(常量区)
  globalVar在哪里?____   staticGlobalVar在哪里?____
  staticVar在哪里?____   localVar在哪里?____
  num1 在哪里?____
  char2在哪里?____   *char2在哪里?___
  pChar3在哪里?____      *pChar3在哪里?____
  ptr1在哪里?____        *ptr1在哪里?____

  答案:

  globalVar在哪里?__C__  staticGlobalVar在哪里?__C__

  staticVar在哪里?__C__  localVar在哪里?__A__

  num1 在哪里?__A__

  

  char2在哪里?__A__  *char2在哪里?__A_

  pChar3在哪里?__A__   *pChar3在哪里?__D__

  ptr1在哪里?__A__    *ptr1在哪里?__B__

 

静态变量在静态区,临时变量在栈区。
malloc,realloc,calloc开辟的在堆区。
char2是一个字符数组,在栈区开辟了一个新空间,将常量字符串的内容拷贝过来初始化这块空间,
所以*char2也是在栈区。
pchar3是一个指向常量字符串的指针,解引用*pchar3是常量字符串在常量区。
说明:
1. 又叫堆栈--非静态局部变量/函数参数/返回值等等, 栈是向下增长的
2. 内存映射段是高效的I/O映射方式,用于装载一个共享的动态内存库。用户可使用系统接口
创建共享共享内存,做进程间通信。
3. 用于程序运行时动态内存分配, 堆是上增长的
4. 数据段--存储全局数据和静态数据。
5. 代码段--可执行的代码/只读常量。

 这里留下一个面试题,大家可以思考思考,查阅相关内容。

 malloc/calloc/realloc的区别?

2.C++内存管理方式

        C++提出了自己的内存管理方式:通过new和delete 操作符 进行动态内存管理

  2.1new/delete操作内置类型

void Test2()
{
	//动态申请1个int类型的空间
	int* ptr1 = new int();
	//动态申请1个int类型的空间并初始化为10
	int* ptr2 = new int(10);
	//动态申请10个int类型的空间
	int* ptr3 = new int[10];

	delete ptr1;
	delete ptr2;
	//匹配[],释放10个空间
	delete[] ptr3;
}

注意:申请和释放单个元素的空间,使用new和delete操作符。
申请和释放连续的空间,使用 new[ ]和delete[ ]。注意:匹配起来使用。

  2.2new/delete操作自定义类型

new/deletemalloc/free最大区别是 new/delete对于[自定义类型]除了开空间还会调用构造函数和析构函数

class A
{
public:
	A(int a = 0)
		: _a(a)
	{
		cout << "A():" << this << endl;
			
	}
	~A()
	{
		cout << "~A():" << this << endl;
	}
private:
	int _a;
};
int main()
{
	// new/delete 和 malloc/free最大区别是 new/delete对于[自定义类型]除了开空间还会调用构造函数和析构函数
	A* p1 = (A*)malloc(sizeof(A));
	A* p2 = new A(1);
	free(p1);
	delete p2;
	return 0;
}

 运行可以看到,构造函数和析构函数被new和delete调用了。

2.1中我们强调要[ ]匹配,我们举2个习题来看看:

 

以下代码中,A 的构造函数和析构函数分别执行了几次:    ( )  

A*pa=new A[10];

delete []pa;

答案:10,10

以下代码中,A 的构造函数和析构函数分别执行了几次:    ( )  

A*pa=new A[10];

delete pa;

答案:10,1

3.operator new与operator delete函数

  3.1operator new

/*
operator new:该函数实际通过malloc来申请空间,当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);
}

  3.2operator delete

/*
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!!
	_free_dbg(pUserData, pHead->nBlockUse);
	
    __FINALLY
		_munlock(_HEAP_LOCK);  /* release other threads */
	__END_TRY_FINALLY
		return;
}
/*
free的实现
*/
#define  free(p)  _free_dbg(p, _NORMAL_BLOCK)
        通过上述两个全局函数的实现知道,operator new 实际也是通过malloc来申请空间,如果
malloc申请空间成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施
就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。

4.new和delete的实现原理

  4.1内置类型

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

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

 今天的分享就到这里,希望大家能有所收获。

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

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

相关文章

【C++进阶之路】初始C++语法(上)

文章目录前言一.命名空间命名冲突命名空间的使用展开命名空间作用域限定符访问作用域命名空间的合并命名空间的嵌套二.输入输出打印流插入运算符输入流提取运算符三.缺省参数全缺省半缺省跨文件缺省函数参数缺省参数的使用格式四.函数重载参数个数不同参数类型不同参数顺序不同…

ubuntu20 qt6.4.3 ustc镜像安装 xdma

文件下载地质 命令 ./qt-unified-linux-x64-4.5.2-online.run --mirror https://mirrors.ustc.edu.cn/qtproject没有镜像就下砸错误hash verification while downloading,this is temporary error,please retry 部分安装器不支持 --mirror cd ~/workspace/dma_ip_drivers/X…

RCIE练习题2之BGP4+配置

R4-R10共7台设备,运行BGP 4+路由协议,其中R4和R5、R6之间为EBGP邻居,其余设备之间为IBGP邻居,将R4 loopback 0的IPv6地址通过重分发方式引入BGP 4+,不得引入多余路由,在R5-R10上均可学习到R4的loopback 0 IPv6地址,同时通过合适配置使得R4上能够学习到R5-R10的loopback …

Excel技能之数据验证,总有一款适合你

用户填写的内容&#xff0c;是未知的&#xff0c;不可靠的。但是&#xff0c;我们要对数据的规范、格式、条件做出限制&#xff0c;既能保证数据的质量&#xff0c;也能统一每个人的行为。最大限度去避免垃圾数据的录入&#xff0c;眼不见心不烦&#xff0c;让心情美美的。 数…

Cont. DB Project ----- MySQL Python Project

Function achieve &#xff08;Cont.&#xff09; Item Search 添加一个新函数search_item&#xff0c;用于实现商品搜索的功能。参数&#xff1a;keyword (为了模糊查询) # search items by keywords def search_item(keyword):cursor, db connect_database()sql f"SE…

milovski-V-XXXXXX勒索病毒数据恢复|金蝶、用友、管家婆、OA、速达、ERP等软件数据库恢复

目录 前言&#xff1a; 一、勒索病毒milovski-V-XXXXXXXX的危害 二、milovski-V-XXXXXXXX勒索病毒的数据恢复方法 三、milovski-V-XXXXXXXX勒索病毒加密数据恢复案例 四、如何防范勒索病毒攻击 前言&#xff1a; 在当今互联网时代&#xff0c;勒索病毒已成为企业信息安全面…

掌握机器学习中的“瑞士军刀”XGBoost,从入门到实战

文章目录1 XGBoost简介2 XGBoost的算法优势3 安装XGBoost库4 回归模型5 分类模型6 XGBoost调参作为机器学习领域中的“瑞士军刀”&#xff0c;XGBoost在各大数据科学竞赛中屡获佳绩。本篇博客将为大家介绍如何使用Python中的XGBoost库&#xff0c;从入门到实战掌握XGBoost的使用…

iot-Scada免费Scada组态软件系列教程4-二次开发与版本部署

iot-Scada免费Scada组态软件系列教程 系列文章目录 iot-Scada免费Scada组态软件系列教程1-初识iot-Scada iot-Scada免费Scada组态软件系列教程2-架构设计 iot-Scada免费Scada组态软件系列教程3-各模块详细介绍 iot-Scada免费Scada组态软件系列教程4-二次开发与版本部署 前言…

p73 应急响应-WEB 分析 phpjavaweb自动化工具

数据来源 应急响应&#xff1a; 保护阶段&#xff08;护案发现场&#xff0c;断网防止持续渗透&#xff0c;数据备份恢复&#xff09;&#xff0c;分析阶段&#xff08;找到漏洞&#xff09;&#xff0c;复现阶段&#xff08;复现攻击过程&#xff09;&#xff0c;修复阶段&am…

QML控件--DialogButtonBox

文章目录一、控件基本信息二、控件使用三、属性成员四、附加属性成员五、成员函数六、信号一、控件基本信息 Import Statement&#xff1a;import QtQuick.Controls 2.14 Since&#xff1a;Qt 5.8 Inherits&#xff1a;Container 二、控件使用 DialogButtonBox&#xff1a;是…

基于 VITA57.4 标准的单通道 6GSPS 12 位采样 ADC,单通道 6GSPS 16 位采样 DAC 子卡模块

概述 FMC147 是一款单通道 6.4GSPS&#xff08;或者配置成 2 通道 3.2GSPS&#xff09;采样率的 12 位 AD 采集、单通道 6GSPS&#xff08;或配置成 2 通道 3GSPS&#xff09; 采样率 16 位 DA 输出子卡模块&#xff0c;该板卡为 FMC标准&#xff0c;符合 VITA57.4 规范&#x…

业务项目管理软件使用推荐

使用Zoho Projects的运营项目管理简化任务并最大限度地利用资源&#xff0c;该管理已被全球200,000多家公司选中。 一、带领您的团队取得更好的成果 Zoho Projects的多功能业务项目管理软件可帮助您的团队在所有运营流程中保持一致。监控您的运营团队的工作流程以确保每个项目顺…

IGKBoard(imx6ull)-Linux下TTY串口编程

文章目录一、TTY介绍&#xff08;1&#xff09;理解tty&#xff08;2&#xff09;tty设备节点二、tty串口应用编程&#xff08;1&#xff09;串口基本操作【1】打开串口【1】读写数据【1】关闭串口&#xff08;2&#xff09;termios 结构体&#xff08;配置&#xff09;&#x…

如何处理后端返回的复杂数据

将接口的复杂数据结构映射成简单的数据结构 假设我们有一个API&#xff0c;返回以下数据&#xff1a; {"id": 1,"name": "Example API","process_params": {"param1": {"name": "Parameter 1","…

企业数字化转型有哪些好处?

从马车到汽车&#xff0c;从写信到智能手机&#xff0c;每一次技术革新所带来的都是生产力大发展&#xff0c;小到个人、家庭&#xff0c;大到企业、国家&#xff0c;都在每一轮技术革新中获得了好处。 可以说&#xff0c;现在的企业数字化转型&#xff0c;就像是企业管理“工具…

从0学习stm32

1.STM32介绍&#xff1a; ST&#xff1a;指的是意法半导体&#xff1b; M&#xff1a;指定微处理器 使用的是ARMCortex-M3 ARM分成三个系列&#xff1a; Cortex-A: 针对多媒体应用(手机) Cortex-R:针对对实时性和性能有一定要求的场景 Cortex-M&#xff1a;针对低功耗高性…

基于html+css的自适应展示4

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

【案例实践】R语言多元数据统计分析在生态环境中的实践应用

查看原文>>>R语言生物群落分析绘图、多元统计分析、CMIP6、遥感碳储量、GEE林业、InVEST等 生态环境领域研究中常常面对众多的不同类型的数据或变量&#xff0c;当要同时分析多个因变量&#xff08;y&#xff09;时需要用到多元统计分析&#xff08;multivariate sta…

vite+vue3+ts搭建项目八(打包性能优化三:使用CDN)

vitevue3ts搭建项目八&#xff08;打包性能优化三&#xff1a;使用CDN&#xff09; 本文目录vitevue3ts搭建项目八&#xff08;打包性能优化三&#xff1a;使用CDN&#xff09;使用vite-plugin-cdn-import下载npm包在vite.config.ts中通过importToCDN引入CDN参数获取方式可用的…

【事务】本地事务和分布式事务的区别

整理下事务相关的知识点&#xff1a; 文章目录一、事务MySQL事务事务的实现事务的ACID特性事务的隔离级别二、本地事务三、分布式事务认识分布式事务CAP理论BASE理论一、事务 先复习下数据库中学到的事务&#xff1a; MySQL事务 一个事务即一个完整的业务逻辑&#xff0c;如…