目录
operator new函数与operator delete函数
介绍与使用
new与delete是C++用于内存管理的操作符,new的功能是从堆区动态申请空间并返回一个指向该空间的指针,delete的功能是释放堆空间。
new
new后面跟着需要申请空间的类型,如果是要开辟数组空间需要在加上[n],n表示开辟的数量。
可以给初始值,单块空间是在类型后加上(x),x表示初始值,数组空间是在[ ]的后面加上{ }花括号,{ }里面是要初始化的内容。
使用格式
- 指针 指针变量名 = new 类型
- 指针 指针变量名 = new 类型(初始值)
- 指针 指针变量名 = new 类型[个数]
- 指针 指针变量名 = new 类型[个数] {初始内容}
内置类型
new对于内置类型如果花括号里面的初始个数少于[]内的参数,会自动补0
//单个空间
int* ptr1 = new int; //不做初始工作
int* ptr2 = new int(30);
//数组空间
int* ptr3 = new int[5]; //不做初始工作
int* ptr4 = new int[5]{ 1,2,3,4,5 };
int s1 = 0, s2 = 0, s3 = 0, s4 = 0, s5 = 0;
int* ptr5 = new int[5]{ s1,s2,s3,s4,s5, };
自定义类型
new对于自定义类型,会去调用构造函数进行初始化,如果没有指定初始内容就会调用默认构造函数进行初始化
/*
Date(int year = 0,int month = 0, int day = 0)
:_day(day),
_month(month),
_year(year)
{
printf("构造函数\n");
}
*/
//单个空间
Date* pd1 = new Date; //自动调用默认构造函数
Date* pd2 = new Date(2023, 8, 17); //显示调用构造函数
//数组空间
Date* pd3 = new Date[3]{ {2023,6,1},{2023,6,2},{2023,6,3}}; //调用3次构造函数
Date d1(2023, 6, 1), d2(2023, 6, 2), d3(2023, 6, 3);
Date* pd4 = new Date[3]{ d1,d2,d3}; //调用拷贝构造
delete
delete后面跟需要释放空间的指针,如果是释放数组空间需要在后面加上[]。
格式
- delete 指针变量名
- delete[] 指针变量名
内置类型
//单个空间
delete ptr1;
//数组空间
delete[] ptr2;
自定义类型
delete对于自定义类型,会去调用析构函数进行清理工作
//单个空间
delete pd1; //调用析构函数+释放空间
//数组空间
delete[] pd3;
new和delete的实现原理
operator new函数与operator delete函数
首先对于自定义类型new和delete做的工作与malloc和free做的工作基本相似,而对于自定义类malloc只会去申请空间new不仅会申请空间还会去调用构造函数进行初始化工作,free也是同理只会去释放空间delete则是调用析构函数+释放空间。
其次new和delete是用户进行动态内存申请和释放的操作符, 而operator new和operator delete 是用于动态内存分配和释放的操作符重载函数,它们的关系是new会在底层调用operator new函数来申请空间,delete会在底层通过operator delete函数来释放空间。
void* operator new(std::size_t size); // 分配指定大小的内存块,并返回指针
void operator delete(void* ptr); // 释放由指针 ptr 指向的内存块
那既然都是申请和释放空间new与delete为啥不调用malloc与free而是调用operator new与operator delete呢?主要的原因是malloc申请空间失败后的报错方式是返回NULL,而面向对象的语言则更喜欢抛异常,所以C++就搞出了operator new与operator delete。但是operator new实际也是通过malloc来申请空间,operator delete最终也是通过free来释放空间的。
工作过程
new的原理:
- 调用operator new函数申请空间
- 在申请的空间上执行构造函数,完成对象的构造
delete的原理:
- 在空间上执行析构函数,完成对象中资源的清理工作
- 调用operator delete函数释放对象的空间
new T[N]的原理:
- 调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请
- 在申请的空间上执行N次构造函数
delete[]的原理:
- 在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理
- 调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间