在我们C++中有了新的内存管理方式,就是通过new/delete操作符进行动态内存管理,C++通过使用new/delete更加符合了C++面向对象的一个特点,下述new/delete的特点
目录
一.定义对象
1.内置类型的操作
void Test()
{
//动态申请一个int类型的空间
int* p1 = new int;
delete p1;
//动态申请一个int类型的空间并初始化
int* p2 = new int(1);
delete p2;
//动态申请10个int类型的空间
//new[] 和 delete[] 是连续申请和释放空间
int* p3 = new int[10];
delete [] p3;
//动态申请10个int类型的空间并初始化
int* p4 = new int[10]{ 1, 2, 3, 4 };
delete [] p4;
}
下面动图可以简单的观察到,new动态申请的并不进行初始化

2.自定义类型的操作
class A
{
public:
A(int a = 0)
:_a(a)
{
cout << "A(int a = 0)" << endl;
}
~A()
{
cout << "~A()" << endl;
}
private:
int _a;
};
int main()
{
//自定义类型的定义的方式和内置类型的方式基本一致,只是类型不同
A* p1 = new A;
delete p1;
A* p2 = new A(1);
delete p2;
A* p3 = new A[10];
delete[] p3;
A* p4 = new A[10]{1, 2, 3, 4};
delete[] p4;
return 0;
}

我们可以观察到,对于自定义类型,new/delete 会去调用构造函数和析构函数,而malloc/free 不会去调用构造函数和析构函数。
二.分析错误信息
我们了解既然是申请空间,那么肯定会有申请失败的情况,像我们的malloc/realloc/calloc这些函数在申请失败时会返回一个空指针(NULL),而我们的new操作符申请失败了,并不会这样做,而是去抛出异常,抛出异常文章后续会继续跟进。
三.new 的底层机制
1.调用 operator new 全局函数来申请空间(operator new 函数又会去调用 malloc 函数)
2.调用构造函数
补充:
delete也有operator delete 全局函数,它通过调用free来释放空间
我们在调试过程中可观察到底层的汇编代码,便可以看到 new 的底层,如下图

四.malloc/free 和 new/delete 区别
1. malloc/free 是 函数,而 new/delete 是 操作符。
2. malloc/free 申请和释放时不调用构造函数和析构函数,而 new/delete 会调用构造函数和析构函数。
3. malloc 需要去计算开辟空间的大小,而 new 不需要,只需要知道对象的类型和个数。
4. malloc 申请失败返回空指针,因此必须判空,而 new 申请失败则是抛异常。
5. malloc 申请的空间不会初始化,而 new 可以初始化。
6. malloc 返回类型是 void*, 因此在使用时必须进行强转,而 new 不需要进行强转,因为new 后面跟着就是空间的类型。