🌈个人主页:羽晨同学
💫个人格言:“成为自己未来的主人~”
operator new与operator delete函数
new和delete是用户进行动态内存申请和释放的操作符,operator new和operator delete是系统提供的全局函数,new在底层调用operator new全局函数来申请空间,delete在底层通过operator delete全局函数来释放空间。
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
using namespace std;
class A
{
public:
A(int a = 0)
:_a(a)
{
cout << "A(int a = 0)" << endl;
}
A(int a1, int a2)
{
cout << "A(int a1, int a2)" << endl;
}
A(const A& aa)
:_a(aa._a)
{
cout << "A(const A& aa)" << endl;
}
A& operator=(const A& aa)
{
cout << "A& operator=(const A& aa)" << endl;
if (this != &aa)
{
_a = aa._a;
}
return *this;
}
~A()
{
cout << "~A()" << endl;
}
private:
int _a;
};
int main()
{
A* p2 = new A;
delete p2;
return 0;
}
operator new等于malloc函数加上构造函数。
operator delete等于free函数加上析构函数。
而在其中,还加入了报错机制
double Division(int a, int b)
{
//当b==0时抛出异常
if (b == 0)
throw"Division by zero condition!";
else
return((double)a / (double)b);
}
void Func()
{
int len, time;
cin >> len >> time;
cout << Division(len, time) << endl;
}
int main()
{
try
{
Func();
}
catch (const char* errmsg)
{
cout << errmsg << endl;
}
catch (...)
{
cout << "unkown exception" << endl;
}
return 0;
}
接下来给大家展示一下new相较于C语言中的malloc的好处
struct ListNode
{
ListNode* _next;
int _val;
ListNode(int val)
:_next(nullptr)
,_val(val)
{}
};
void func()
{
//new如果失败了,抛异常,不需要再检查返回值
ListNode* n1 = new ListNode(1);
ListNode* n2 = new ListNode(2);
ListNode* n3 = new ListNode(3);
n1->_next = n2;
n2->_next = n3;
delete n1;
delete n2;
delete n3;
}
这样做的话,省去了我们之前在C语言当中的BuyNode的函数用法,使得代码的可读性更高。
struct ListNode
{
ListNode* _next;
int _val;
ListNode(int val)
:_next(nullptr)
,_val(val)
{}
};
void func()
{
//new如果失败了,抛异常,不需要再检查返回值
ListNode* n1 = new ListNode(1);
ListNode* n2 = new ListNode(2);
ListNode* n3 = new ListNode(3);
int* p1 = new int[100 * 1024 * 1024];
int* p2 = new int[100 * 1024 * 1024];
int* p3 = new int[100 * 1024 * 1024];
int* p4 = new int[100 * 1024 * 1024];
int* p5 = new int[100 * 1024 * 1024];
int* p6 = new int[100 * 1024 * 1024];
int* p7 = new int[100 * 1024 * 1024];
int* p8 = new int[100 * 1024 * 1024];
int* p9 = new int[1024*1024*1024*1024*1024*1024*102444*1024*100 * 1024 * 1024*1024];
n1->_next = n2;
n2->_next = n3;
delete n1;
delete n2;
delete n3;
}
int main()
{
try
{
func();
}
catch (const exception& e)
{
cout << e.what() << endl;
}
return 0;
}
通过上面的代码我们可以看到,当new使用异常的时候,会出现报错情况
new和delete的实现原理
内置类型
如果申请的是内置类型的空间,new和malloc,delete和free基本类似,不同的地方是:new/delete申请和释放的是单个元素的空间,new[]和delete[]申请的是连续空间,而且new在申请空间失败时会抛出异常,malloc会返回NULL
自定义类型
- 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来释放空间。