6.malloc,free && new,delete
这个问题很有意思,也是重点需要关注的问题。malloc()和free()是C语言中动态申请内存和释放内存的标准库中的函数。而new和delete是C++运算符、关键字。new和delete底层其实还是调用了malloc和free。它们之间的区别有以下几个方面:
①:malloc和free是函数,new和delete是运算符。
②:malloc在分配内存前需要大小,new不需要。
例如:int *p1 = (int *)malloc(sizeof(int));
int *p2 = new int; //int *p3 = new int(10);
malloc时需要指定大小,还需要类型转换。new时不需要指定大小因为它可以从给出的类型判断,并且还可以同时赋初始值。
③:malloc不安全,需要手动类型转换,new不需要类型转换。
详见上一条。
④:free只释放空间,delete先调用析构函数再释放空间(如果需要)。
与第⑤条对应,如果使用了复杂类型,先析构再call operator delete回收内存。
⑤:new是先调用构造函数再申请空间(如果需要)。
与第④条对应,我们在调用new的时候(例如int *p2 = new int;这句代码 ),底层代码的实现是:首先push 4字节(int类型的大小),随后call operator new函数分配了内存。由于我们这句代码并未涉及到复杂类型(如类类型),所以也就没有构造函数的调用。如下是operator new的源代码,也是new实现的重要函数:
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);
}
我们可以看到,首先malloc(size)申请参数字节大小的内存,如果失败(malloc失败返回0)则进入判断:如果_callnewh(size)也失败的话,抛出bad_alloc异常。_callnewh()这个函数是在查看new handler是否可用,如果可用会释放一部分内存再返回到malloc处继续申请,如果new handler不可用就会抛出异常。
⑥:内存不足(开辟失败)时处理方式不同。
malloc失败返回0,new失败抛出bad_alloc异常。
⑦:new和malloc开辟内存的位置不同。
malloc开辟在堆区,new开辟在自由存储区域。
⑧:new可以调用malloc(),但malloc不能调用new。
new就是用malloc()实现的,new是C++独有malloc当然无法调用。