当前位置: 代码网 > it编程>编程语言>C/C++ > C++内存管理(区别C语言)深度对比

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

2024年08月02日 C/C++ 我要评论
C++ 内存管理

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

前言

一、内存的分区

  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

五、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在释放空间前会调用析构函数完成空间中资源的清理

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com