1. malloc和new都是在堆上开辟内存的
malloc只负责开辟内存,没有初始化功能。
new不但开辟内存,还可以进行初始化。new int(10);
new分配内存按照数据类型进行分配,malloc分配内存按照指定的大小分配;
2. malloc是函数,new是运算符
new返回的是指定对象的指针,而malloc返回的是void*,因此malloc的返回值一般都需要进行类型转化。
malloc是C语言的库函数,开辟内存需要传入字节数,如malloc(100);表示在堆上开辟了100个字节的内存,返回void*,表示分配的堆内存的起始地址,因此malloc的返回值需要强转成指定类型的地址;
必须指明申请内存空间的大小
new不仅分配一段内存,而且会调用构造函数,malloc不会。
new是运算符,开辟内存需要指定类型,返回指定类型的地址,因此不需要进行强转。
3. malloc开辟内存失败返回NULL,new开辟内存失败抛出bad_alloc类型的异常
需要捕获异常才能判断内存开辟成功或失败,new运算符其实是operator new函数的调用,它底层调用的也是malloc来开辟内存的,new它比malloc多的就是初始化功能,对于类类型来说,所谓初始化,就是调用相应的构造函数。
4. malloc开辟的内存永远是通过free来释放的;而new单个元素内存,用的是delete,如果new[]数组,用的是delete[]来释放内存的。
5. malloc开辟内存只有一种方式,而new有四种分别是普通的new(内存开辟失败抛出bad_alloc异常), nothrow版本的new,const new以及定位new。
memcpy等,realloc函数能不能在C++中使用,绝对不能,因为这些函数进行的都是内存值拷贝(也就是对象的浅拷贝),会发生浅拷贝这个严重的问题!
operator new ()全局函数原型:
/*
operator new:该函数实际通过malloc来申请空间,当malloc申请空间成功时直接返回;申请空间失败,尝试
执行空 间不足应对措施,如果改应对措施用户设置了,则继续申请,否则抛异常。
*/
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
// 如果申请内存失败了,这里会抛出bad_alloc 类型异常
static const std::bad_alloc nomem;
_RAISE(nomem);
}
return (p);
}
operator delete ()全局函数原型:
/*
operator delete: 该函数最终是通过free来释放空间的
*/
void operator delete(void *pUserData)
{
_CrtMemBlockHeader * pHead;
RTCCALLBACK(_RTC_Free_hook, (pUserData, 0));
if (pUserData == NULL)
return;
_mlock(_HEAP_LOCK); /* block other threads */
__TRY
/* get a pointer to memory block header */
pHead = pHdr(pUserData);
/* verify block type */
_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));
_free_dbg( pUserData, pHead->nBlockUse );
__FINALLY
_munlock(_HEAP_LOCK); /* release other threads */
__END_TRY_FINALLY
return;
}
/*
free的实现
*/
#define free(p) _free_dbg(p, _NORMAL_BLOCK)
步骤
- new的原理:
调用operator new函数申请空间;
在申请的空间上执行构造函数,完成对象的构造; - delete的原理:
在空间上执行析构函数,完成对象中资源的清理工作;
调用operator delete函数释放对象的空间; - new[N]的原理:
调用operator new[]函数,在operator new[]中实际调用operator new函数完成N个对象空间的申请;
在申请的空间上执行N次构造函数; - delete[N]的原理:
在释放的对象空间上执行N次析构函数,完成N个对象中资源的清理;
调用operator delete[]释放空间,实际在operator delete[]中调用operator delete来释放空间;