目录
一.new/delete用法规则
1.对于内置类型
//1.在堆上开辟空间但不初始化
int* p1 = new int;
//2.在堆上开辟空间的同时初始化
int* p2 = new int(10);
//3.在堆上开辟10个连续的int空间但不初始化
int* p3 = new int[10];
//4.在C++11规定,可以给连续空间开辟的同时初始化
int* p4 = new int[10]{ 1,2,3,4,5,6,7,8,9,10 };
//5.清理并且释放空间
delete p1;
delete p2;
delete[] p3;
delete[] p4;
对于内置类型而言,malloc/new、free/delete并没有本质上的区别,如果开辟连续空间使用delete直接清理并释放的话不一定会报错,但建议配套使用new/delete、new[]/delete[]
2.对于自定义类型
class Date
{
public:
Date(int year = 1, int month = 1, int day = 1)
:_year(year),_month(month),_day(day)
{}
private:
int _year;
int _month;
int _day;
};
int main()
{
//对于自定义类型
//1.在堆上开辟空间但不初始化,自动调用默认构造
Date* dp1 = new Date;
//2.在堆上开辟空间的同时初始化,调用构造函数
Date* dp2 = new Date(2022, 8, 14);
//3.在堆上开辟10个连续的int空间但不初始化,自动调用10次默认构造
Date* dp3 = new Date[10];
//4.在C++11规定,可以给连续空间开辟的同时初始化,调用10次构造函数
//两种方式
Date* dp4 = new Date[10]{ Date(1,1,1),Date(2,2,2),Date(3,3,3),\
Date(4,4,4),Date(5,5,5),Date(6,6,6),\
{ 7, 7, 7 }, { 8, 8, 8 }, { 9, 9, 9 }, { 10,10,10 } };
delete dp1;
delete dp2;
delete[] dp3;
delete[] dp4;
return 0;
}
对于自定义类型而言,必须严格遵守new/delete、new[]/delete[]配套使用,否则一定报错
3.new/delete与malloc/free的区别
1.体现在对于自定义类型的处理不同
对于自定义类型new会做两件事
1).在堆上申请空间 2).调用构造函数初始化
对于自定义类型delete会做两件事
1).调用析构函数清理对象中的资源 2).释放空间
结论:new/delete就是为自定义类型准备的!
2.体现在对于开辟空间失败的处理不同
1).malloc失败直接返回NULL
2).new失败,需要检查返回值,抛出异常
二.new/delete的实现原理
从汇编角度来看new的底层调用了operator new与构造函数,而operator new的底层实际调用的malloc ,那么operator new与malloc最大的区别,实际本质上operator new是在malloc的基础上封装了一层异常处理;delete的底层则是调用了operator delete与析构函数。实际上new/delete的空间是由malloc开辟,由free释放。
三.总结
new/malloc、delete/free的区别
对于内置类型
无本质区别,唯一的区别就是new开辟失败抛异常,malloc开辟失败返回NULL
对于自定义类型
new
1.调用operator new
2.调用构造
delete
1.调用析构
2.调用operator delete
关系图