内存管理方式
void Test
{
int* ptr1 = new int; //动态申请一个int类型的空间
int* ptr2 = new int(10);//动态申请一个int类型的空间并初始化为10
int* ptr3 = new int[10];//动态申请10个int类型的空间
delete ptr1;
delete ptr2; //释放单个空间
delete[] ptr3;//释放连续的空间
}
申请自定义类型空间时,new会调用构造函数,delete会调用析构函数
new/delete底层
- new和delete底层分别通过operator new来申请空间和operator delete来释放空间
- operator new和operator delete不是运算符重载而是全局函数
- operator new和operator delete时malloc和free的封装,但是错误时会抛异常
实现原理
定位new表达式
- 在已分配的原始内存空间中调用构造函数初始化一个对象
- new(place_address)type或new(place_address)type(initializer-list),place_address必须是一个指针,initializer-list是类型的初始化列表
- 一般配合内存池使用,因为内存池分配的内存没有初始化,所以如果自定义类型的对象,需要定位new表达式进行显式调用构造函数进行初始化
new/delete和malloc/free
- malloc/free是函数,new/delete是操作符
- malloc/free只负责动态分配内存空间,new/delete除了动态分配内存空间还会调用构造函数完成对象的初始化和调用析构函数完成空间资源的清理
- malloc需手动计算大小且返回值为void*,使用时必须强转,new不需要计算大小,并且返回对应类型的指针
- malloc申请失败返回NULL,new申请失败会抛异常,所以malloc使用需判空,new使用需捕获异常
- new/delete比malloc/free效率低点,因为new/delete底层封装了malloc/free
内存泄漏
内存泄漏并不是指内存在物理上消失,而是指应用程序分配某段内存后,失去了对该段内存的控制,即动态开辟的内存空间未释放