【C++】内存管理

1.C/C++内存分布

在这里插入图片描述

1.栈区从高地址向低地址增长,存放非静态局部变量,函数参数等
2.堆区从低地址到高地址增长,存放malloc,new出来的变量。
3.数据段存放全局变量和静态变量
4.代码段存放只读常亮,可执行代码。

2.从C语言的内存管理引入

C语言动态内存管理: link.
这里面是博主对于c语言出现的动态开辟内存管理的总结,包括基本使用和常见错误

3.C++内存管理

在c++中我们系统定义了2个关键词来用于对内存的管理。

针对内置类型的基本操作

注意:申请和释放单个元素的空间,使用new和delete操作符,申请和释放连续的空间,使用new[ ]和delete[ ]
在这里插入图片描述

管理对象

	//申请空间
	int* ptr = new int;
	
	//申请空间并初始化
	int* ptr2 = new int(1);
	delete ptr;
    delete ptr2;
	

管理对象数组

    //申请大小为4*10的连续空间
	int* arr = new int[10];
	//c++98不允许连续空间初始化
	//c++11后支持
	//	int *arr =new[10](1);(是错误代码)  
    delete[] arr;

针对自定义类型的基本操作

相比于内置类型,自定义类型的new和delete功能更丰富:
new会调用构造函数去初始化(new仅仅是对空间的申请)
delete会调用析构函数去清理空间

#include <iostream>
using namespace std;
class Test
{
    
    
public:
	Test()
		: _data(0)
	{
    
    
		cout << "Test():" << this << endl;
	}
	~Test()
	{
    
    
		cout << "~Test():" << this << endl;
	}
private:
	int _data;
};
void Test2()
{
    
    
	// 申请单个Test类型的空间
	Test* p1 = (Test*)malloc(sizeof(Test));
	free(p1);
	// 申请10个Test类型的空间
	Test* p2 = (Test*)malloc(sizeof(Test) * 10);
	free(p2);
}
int main()
{
    
    
	Test* t = new Test;
	delete t;
	return 0;
}

在这里插入图片描述可以看出他们的构造函数和析构函数都调用了,并且是一个物理空间。
注意:
1.必须要有默认构造才可以进行动态空间的开辟。

operator new和operator delete

1.new和delete是用户进行动态内存申请和释放的操作符,operator new 和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。
2.operator new 实际也是通过malloc来申请空间,如果malloc申请空间
成功就直接返回,否则执行用户提供的空间不足应对措施,如果用户提供该措施就继续申请,否则就抛异常。operator delete 最终是通过free来释放空间的。

可以理解为operator new就是封装了malloc和异常处理机制。
在这里插入图片描述

new&delete实现原理

void test1(){
    
    
//内置类型
	int* ptr = new int;
	//new->operator new->malloc
	delete ptr;
	//delete->operator delete->free
	int* ptr1 = new int[10];
	//new[]-> operator new[]-> operator new->malloc
	delete[] ptr1;
	//delete[]->operator delete[]->operator delete->free

//自定义类型
	Test* t1 = new Test;
	//new->operator new->malloc->构造
	delete t1;
	//delete->析构->operator delete->free
	Test* t2 = new Test[10];
	//new[]->operator new[]->operator new->malloc->10构造
	delete t2;
	//delete[]->10析构->operator delete[]->operator delete->free


}

malloc/free和new/delete区别

  1. malloc和free是函数,new和delete是操作符
  2. malloc申请的空间不会初始化,new可以初始化
  3. malloc申请空间时,需要手动计算空间大小并传递,new只需在其后跟上空间的类型即可
  4. malloc的返回值为void*, 在使用时必须强转,new不需要,因为new后跟的是空间的类型
  5. malloc申请空间失败时,返回的是NULL,因此使用时必须判空,new不需要,但是new需要捕获异常
  6. 申请自定义类型对象时,new在申请空间后会调用构造函数完成对象的初始化,delete在释放空间前会调用析构函数完成空间中资源的清理

猜你喜欢

转载自blog.csdn.net/zhaocx111222333/article/details/114982845