C++内存管理(区别C语言)深度对比

news2024/9/21 0:37:47

欢迎来到我的Blog,点击关注哦💕

前言

前面已经介绍了类和对象,对C++面向对象编程已经有了全面认识,接下来要学习对语言学习比较重要的是对内存的管理。

一、内存的分区

  1. 代码区:存放程序的机器指令,通常是可共享的,并且通常为只读的,以防止程序意外修改自身的代码。
  2. 全局/静态存储区:存放全局变量和静态变量,这些变量在程序的整个生命周期内都存在。
  3. 堆区:用于动态分配内存,程序运行时根据需要通过malloc、calloc、realloc等函数在堆区中分配内存空间。
  4. 栈区:存放函数的局部变量和函数调用的参数,由编译器自动管理,遵循后进先出的原则。
  5. 常量区:存放常量数据,如字符串字面量,这些数据在程序运行期间不可修改。
  6. 代码区:存放程序的二进制代码,是程序执行指令的存储空间。

在这里插入图片描述

二、C语言中的内存管理(参考)

  • malloc函数用于动态分配指定大小的内存空间,并返回指向该内存的指针。如果分配成功,返回非NULL指针;否则返回NULL。
  • calloc函数除了分配内存外,还会将分配的内存初始化为零。
  • realloc函数用于调整已分配内存的大小,可能会移动内存块以适应新的大小要求。
  • free函数用于释放之前通过动态内存分配函数分配的内存空间

三、C++中的内存管理

C++内存分配

不同于C语言,C++有着自己独立动态内存开辟的方法:

​ 主要通过newdelete操作符来实现new操作符用于分配单个对象或数组,而deletedelete[]分别用于释放这些对象或数组所占用的内存.

下面是new和delete应用的实例:

 //动态申请一个int大小空间
int* p0 = new int;
//动态申请一个int大小空间并且初始化为0
int* p1 = new int (0);
//动态申请10个int大小空间
int* p2 = new int[10];
//动态申请10个int大小空间并且初始化为0
int* p3 = new int[10] {0};

delete p0;
delete p1;
delete[] p2;
delete[] p3; 

注意

  1. 不要使用delete释放非new开辟的空间
  2. 不要使用delete释放同一块空间两次
  3. 如果使用new [ ] 开辟数组进行内存分配,应该使用delete [ ] 来释放
  4. 如果new对一个实体进行内存分配,应该使用delete(没有方括号)进行释放

四、new 和 delete深度探索

有关operator new 和operator delete

operator new

  • operator new是一个特殊的操作符,用于动态分配内存。它与new操作符密切相关,但它们在语义上有所区分。

  • new操作符是一个高级操作符,它不仅分配内存,还自动调用对象的构造函数。

  • operator new仅负责分配内存,不涉及对象的构造。

  • operator new可以被重载,以便为特定的类或全局范围提供自定义的内存分配策略

  • operator new:该函数实际通过``malloc来申请空间,当malloc`申请空间成功时直接返回

  • 申请空间失败, 尝试执行空 间不足应对措施,如果改应对措施用户设置了,则继续申请,否则抛异常。

通俗的讲 ,new 不仅仅可以进行空间开辟,针对自定义类型会调用其构造函数,而new也是调用重载(operator new),进行内存的分配,然而 operator new 进行内存分配是通过malloc进行实现的,这正是区别于C语言的其中一点。

关于时间类和汇编语言:

class Date
{
public:
	Date(int year = 1,int month = 1,int day = 1)
		:_year(year)
		,_month(month)
		,_day(day)
	{}
	~Date()
	{
		_year = 0;
		_month = 0;
		_day = 0;
	}

private:
	int _year = 1;
	int _month = 1;
	int _day = 1;
};

	Date* d1 = new Date;
00007FF62A0D19FC  mov         ecx,0Ch  
00007FF62A0D1A01  call        operator new (07FF62A0D103Ch)//调用operator new内存分配
00007FF62A0D1A06  mov         qword ptr [rbp+108h],rax  
00007FF62A0D1A0D  cmp         qword ptr [rbp+108h],0  
00007FF62A0D1A15  je          main+5Dh (07FF62A0D1A3Dh)  
00007FF62A0D1A17  mov         r9d,1  
00007FF62A0D1A1D  mov         r8d,1  
00007FF62A0D1A23  mov         edx,1  
00007FF62A0D1A28  mov         rcx,qword ptr [rbp+108h]  
00007FF62A0D1A2F  call        Date::Date (07FF62A0D13D4h)    // 调用构造函数
00007FF62A0D1A34  mov         qword ptr [rbp+118h],rax  
00007FF62A0D1A3B  jmp         main+68h (07FF62A0D1A48h)  
00007FF62A0D1A3D  mov         qword ptr [rbp+118h],0  
00007FF62A0D1A48  mov         rax,qword ptr [rbp+118h]  
00007FF62A0D1A4F  mov         qword ptr [rbp+0E8h],rax  
00007FF62A0D1A56  mov         rax,qword ptr [rbp+0E8h]  
00007FF62A0D1A5D  mov         qword ptr [d1],rax 

operator delete

  • operator delete 是一个全局函数,用于释放之前通过 operator new 分配的内存。
  • 它是 new 操作符的逆运算,负责在内存释放时执行必要的清理工作。
  • operator delete 通常在 delete 表达式中被隐式调用,用于释放单个对象或对象数组的内存
  • 在空间上执行析构函数,完成对象中资源的清理工作
  • 调用operator delete函数释放对象的空间(通过free)
00B72150	push	ebp	已用时间<=1ms	
00B72151	mov	ebp,esp	
00B72153	sub	esp,0cCh	
00B72159	push	ebx	
00B7215A	push	esi	
00B7215B	push	edi	
00B7215C	push	ecx	
00B7215D	lea	edi,[ebp-0Ch]	
00B72160	mov	ecx,3	
00B72165	mov	eax,0cccccccch	
00B7216A	rep stos	dword ptr es:[edi]	
00B7216C	pop	ecx	
00B7216D	mov	dword ptr [this],ecx	
00B72170	mov	ecx,dword ptr [this]	
00B72173	call	A::~A (0B7154Bh)			//调用析构函数
00B72178	mov	eax,dword ptr [ebp+8]	
00B7217B	and	eax,1	
00B7217E	je	__call_empty_init_list_helper<A>+0Eh (0	
00B72180	push	4	
00B72182	mov	eax,dword ptr [t.	ebp	15990024	
00B72185	push	eax	
00B72186	call	operator delete (0B710AAh)	//释放空间
00B7218B	add	esp,8	
00B7218E	mov	eax,dword ptr [this]	
00B72191	pop	edi	
00B72192	pop	esi                                                         

小结

new 和delete 调用的时候内部调用的顺序

  • new 先进行空间的开辟(malloc),在进行对象的实例化
  • delete先进行析构函数的调用,进行资源的销毁,在进行空间的释放(free
new
operatornew
构造函数
delete
析构函数
operatordelete

五、replacement new

在C++中new操作符通常用于在堆上分配内存并调用对象的构造函数。除了常规的new操作符外,C++还提供了operator newplacement new两种替代机制。operator newnew操作符内部使用的函数,可以被重载以提供自定义的内存分配策略。而placement new是一种特殊的new表达式,它允许在已分配的内存上构造对象,而不是分配新的内存。

//用法
new(place_address)type

应用场景:

池化技术:

化技术在C++编程中通常指的是预先分配一定数量的资源(如内存、线程等)并存储在一个“池”中,以便在程序运行时可以快速地从中获取和返回资源,而不是每次都进行昂贵的动态分配和释放操作。

这个就是进行已有空间进行对象实例化

六、C语言和C++内存分配的区别

区别malloc free new delete

  1. mallocfree是函数,而newdelete是操作符
  2. malloc不可以初始化而new可以初始化
  3. malloc进行内存分配的时候是手动计算空间的大小,而new后面跟类型,大小在 [ ]中指定
  4. malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型
  5. malloc申请空间失败是返回NULL,而new申请空间失败是捕获异常
  6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间 后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理

void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型
5. malloc申请空间失败是返回NULL,而new申请空间失败是捕获异常
6. 申请自定义类型对象时,malloc/free只会开辟空间,不会调用构造函数与析构函数,而new在申请空间 后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理

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

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

相关文章

js实现数组的下标为n的对象后面新增一条对象

前言&#xff1a; js实现数组的下标为n的对象后面新增一条对象 实现方法&#xff1a; arr.splice(1, 0, obj); splice 参数1: 数组里面的第几个元素&#xff0c;你希望在第几个对象后面新增参数2: 0 表示不删除任何元素参数3: 插入的新对象 let arr [{},{},{},{}] let obj…

vue使用echarts开发大屏可视化(附echarts案例资源)

近年来&#xff0c;可视化在前端领域是越来越多。最近投入的一个项目就是关于大屏可视化&#xff0c;基本就是用到了echarts&#xff0c;所以项目结束后&#xff0c;我也来总结一下如何在Vue中去引入echarts并使用。 文章目录 一、echarts案例网站可视化社区(https://www.makea…

Zoho Mail企业邮箱好用吗?

企业在选择企业邮箱时需要考虑三大因素&#xff0c;一是安全隐私&#xff0c;二是功能易用&#xff0c;三是产品价格。作为国际排行前五的企业邮箱&#xff0c;Zoho邮箱好用吗&#xff1f;本文将为您详细介绍Zoho邮箱的功能、安全性和产品价格。 一、安全隐私 1、数据加密与安…

MySQL----初始数据类型

前言 一、tinyint 范围&#xff1a;-128-----127 在MySQL中&#xff0c;整型可以指定是有符号的和无符号的&#xff0c;默认是有符号的。可以通过UNSIGNED来说明某个字段是无符号的。如果我们向mysqlt特定的类型中插入不合法的数据&#xff0c;Mysq一般会直接拦截&#xff0c…

【HarmonyOS学习】定位相关知识(Locationkit)

简介 LocationKit提供了定位服务、地理围栏、地理编码、逆地理编码和国家码等功能。 可以实现点击获取用户位置信息、持续获取位置信息和区域进出监控等多项功能。 需要注意&#xff0c;需要确定用户已经开启定位信息&#xff0c;一下的代码没有做这一步的操作&#xff0c;默…

p17面试题

品茗面试题 1.交换两个int变量的值&#xff0c;不能使用第三个变量&#xff0c;即a3,b5,交换后&#xff0c;a5,b3&#xff1b; #include<stdio.h> //int main(){ // //打印函数&#xff0c;引用头文件.stdio.h // printf("hello world\n");//打印函数 …

C++STL详解(二)——string类的模拟实现

首先&#xff0c;我们为了防止命名冲突&#xff0c;我们需要在自己的命名空间内实现string类。 一.string类基本结构 string类的基本结构和顺序表是相似的&#xff0c;结构如下&#xff1a; //.h namespace kuzi {class string{private:char* _str;//字符串size_t _size;//长…

算法基础之回溯法

本文将详细介绍回溯法的基本原理和适用条件&#xff0c;并通过经典例题辅助读者理解回溯法的思想、掌握回溯法的使用。本文给出的例题包括&#xff1a;N皇后问题、子集和问题。 算法原理 在问题的解空间树中&#xff0c;回溯法按照深度优先的搜索策略&#xff0c;从根结点出发…

LDR6020:重塑iPad一体式有线键盘体验的创新力量

在移动办公与娱乐日益融合的时代&#xff0c;iPad凭借其强大的性能和便携性&#xff0c;成为了众多用户不可或缺的生产力工具。然而&#xff0c;为了进一步提升iPad的使用体验&#xff0c;一款高效、便捷的键盘成为了不可或缺的配件。今天&#xff0c;我们要介绍的&#xff0c;…

TYPE-C接口PD取电快充协议芯片ECP5701:支持PD 2.0和PD 3.0(5V,9V,12V,15V,20V)

随着智能设备的普及&#xff0c;快充技术成为了越来越多用户的刚需。而TYPE-C接口作为新一代的USB接口&#xff0c;具有正反插、传输速度快、充电体验好等优点&#xff0c;已经成为了快充技术的主要接口形式。而TYPE-C接口的PD&#xff08;Power Delivery&#xff09;取电快充协…

【数据结构】线性结构——数组、链表、栈和队列

目录 前言 一、数组&#xff08;Array&#xff09; 1.1优点 1.2缺点 1.3适用场景 二、链表&#xff08;Linked List&#xff09; 2.1优点 2.2缺点 2.3适用场景 三、栈&#xff08;Stack&#xff09; 3.1优点 3.2缺点 3.3适用场景 四、队列&#xff08;Queue&#xff09; 4.1优点…

【python】Python高阶函数--reduce函数的高阶用法解析与应用实战

✨✨ 欢迎大家来到景天科技苑✨✨ &#x1f388;&#x1f388; 养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; &#x1f3c6; 作者简介&#xff1a;景天科技苑 &#x1f3c6;《头衔》&#xff1a;大厂架构师&#xff0c;华为云开发者社区专家博主&#xff0c;…

Redis常用的5大数据类型

Reids字符串&#xff08;String&#xff09; 设置相同的key&#xff0c;之前内容会覆盖掉 Redis列表&#xff08;List&#xff09; 常用命令 从左往右放值 数据结构 Redis集合&#xff08;set&#xff09; sadd<key><value1><value2>...... 数据结构 Set数据…

前端组件化开发:以Vue自定义底部操作栏组件为例

摘要 随着前端技术的不断演进&#xff0c;组件化开发逐渐成为提升前端开发效率和代码可维护性的关键手段。本文将通过介绍一款Vue自定义的底部操作栏组件&#xff0c;探讨前端组件化开发的重要性、实践过程及其带来的优势。 一、引言 随着Web应用的日益复杂&#xff0c;传统的…

「豆包Marscode体验官」 | 云端 IDE 启动 Rust 体验

theme: cyanosis 我正在参加「豆包MarsCode初体验」征文活动 MarsCode 可以看作一个运行在服务端的远程 VSCode开发环境。 对于我这种想要学习体验某些语言&#xff0c;但不想在电脑里装环境的人来说非常友好。本文就来介绍一下在 MarsCode里&#xff0c;我的体验 rust 开发体验…

Games101学习笔记 Lecture22 Animation(cont.)

Lecture22 Animation(cont. 一、单个粒子模拟Ordinary Differential Equation ODE 常微分方程ODE求解方法——欧拉方法解决不稳定中点法改进欧拉方法自适应步长隐式欧拉方法 二、流体模拟基于位置的方法物质点方法 一、单个粒子模拟 想模拟粒子在场中的运动 Ordinary Differe…

Token Labeling(NeurIPS 2021, ByteDance)论文解读

paper&#xff1a;All Tokens Matter: Token Labeling for Training Better Vision Transformers official implementation&#xff1a;https://github.com/zihangJiang/TokenLabeling 出发点 ViTs的局限性&#xff1a;尽管ViTs在捕捉长距离依赖方面表现出色&#xff0c; 但…

代码随想录算法训练营第五十八天|108.冗余连接、109.冗余连接II

108.冗余连接 题目链接&#xff1a;108.冗余连接 文档讲解&#xff1a;代码随想录 状态&#xff1a;还行 思路&#xff1a; 并查集可以解决什么问题&#xff1a;两个节点是否在一个集合&#xff0c;也可以将两个节点添加到一个集合中。 题解&#xff1a; public class Main {p…

套用BI方案做数据可视化是种什么体验?

在数字化转型的浪潮中&#xff0c;数据可视化作为连接数据与决策的桥梁&#xff0c;其重要性日益凸显。近期&#xff0c;我有幸体验了奥威BI方案进行数据可视化的全过程&#xff0c;这不仅是一次技术上的探索&#xff0c;更是一次对高效、智能数据分析的深刻感受。 初识奥威&a…

.net dataexcel 脚本公式 函数源码

示例如: ScriptExec(""sum(1, 2, 3, 4)"") 结果等于10 using Feng.Excel.Builder; using Feng.Excel.Collections; using Feng.Excel.Interfaces; using Feng.Script.CBEexpress; using Feng.Script.Method; using System; using System.Collections.Gen…