new/delete 出现的背景:
在C语言中,我们申请空间用malloc,calloc,realloc,释放空间为free,在这样的空间申请后,我们需要对申请空间的状态,进行判断,判断是否申请成功,并且需要对没有申请成功的变量进行处理,在这样的情况下,人们难免可能会忘记判断,导致程序出现异常。
new/delete 实现的原理:
new、delete ,new[] ,delete[], 在实现原理上依旧是调用C语言中的malloc 和 free 进行实现,但由于对malloc,free进行了调用,因此在内部,new对变量 申请的空间进行了判断,并且对没有申请成功的变量进行了处理。
1.这是new在C++中的实现方式,其中 _THROW_NCEE(_XSTD bad_alloc, );这是对new 变量 抛出异常
operator new()函数中可以添加其他的参数,但第一个参数必须是size_t类型的参数
void *__CRTDECL operator new(size_t size) _THROW1(_STD bad_alloc)
{ // try to allocate size bytes
void *p;
while ((p = malloc(size)) == 0)
if (_callnewh(size) == 0)
{ // report no memory
_THROW_NCEE(_XSTD bad_alloc, );
}
return (p);
}
2.这是new[] 在C++中的实现,通过其中代码可见 主要是通过调用new 来创建一段连续的空间
void * operator new[]( size_t cb )
{
void *res = operator new(cb);
RTCCALLBACK(_RTC_Allocate_hook, (res, cb, 0));
return res;
}
3.这是delete 在C++中的实现,由此可见主要是调用free 来释放空间
void operator delete( void * p )
{
RTCCALLBACK(_RTC_Free_hook, (p, 0));
free( p );
}
4.
void operator delete[]( void * p )
{
RTCCALLBACK(_RTC_Free_hook, (p, 0))
operator delete(p);
}
new/delete操作自定义类型的次序:
1.new:
1).申请空间:void *__CRTDECL operator new(size_t size字节数) _THROW1(_STD bad_alloc)
表明依旧是使用C语言中的malloc申请空间,并且进行判断是否申请成功,没有成功,则在函数内部进行处理
operator new()函数中可以添加其他的参数,但第一个参数必须是size_t类型的参数
2).调用构造 :对象初始化
2.delete :
1).调用析构 :将对象中的资源释放掉
2).释放空间:void operator delete(void *pUserData)
调用从语言中的free释放空间
operator new/ operator delete 基本上不需要重载,除非需要看是在什么时候使用,并且申请多长字节等等信息或者需要查看内存泄漏的情形。
3.new T[N]:前四个字节(取决于是否有析构函数)放对象的个数。(目的:保证销毁时销毁对象的次数)
小贴士:这里面申请空间大小有没有多申请4个字节,取决于类成员函数中是否存在析构函数或者编译器是否默认生成析构函数。若类成员函数中没有析构函数,则申请空间时,不多申请4个字节。
1).operator new[](sizeof(T)*N+4)
operator new(sizeof(T)*N+4)
while(p=malloc(字节数)==NULL))
{ if(条件(空间不足的处理))
{ 抛异常}
}
2).调用N次构造对象:
4.delete[] p:
1).调用N次析构函数-->释放每个对象的资源,后构造的先析构,成对出现
2).operator delete[](void* p)-->operator delete(p)--->free(p)
注意:
1. new 和 delete 是C++中提出的关键字,不是函数
2.new 类型,可以初始化,无需强制类型转化
3.new申请的空间不需要对结果判空(原:
4.new申请空间 -->会调用构造函数 delete--->调用析构函数
malloc 不调用构造函数 free 不调用析构函数
new/delete new[]/delete[] malloc/free :匹配使用
否则:内存泄漏、崩溃
小问题:若申请空间与释放空间没有匹配使用,则程序会出现什么样的问题?
答:1.内置类型:如果没有匹配使用,程序也不会出问题--但建议:匹配使用
#include<srtdbg.h>
_crtdumpMemoryLeak()函数:检测是否存在内存泄漏
2.自定义类型出问题:1.内存泄漏 2.程序崩溃