new/delete 与 malloc/free 的区别

来源:互联网 发布:mac视频截图快捷键 编辑:程序博客网 时间:2024/06/05 13:24

new/delete 与 malloc/free有什么区别呢?这是一道面试中经常会被问到的问题。这篇博客将为大家详细解说两者的区别。

1,申请的内存所在位置
new 操作符 从自由存储区上为对象动态分配内存,而malloc 函数从堆上动态分配内存。

2,返回类型安全性
new操作符为对象成功分配内存后,返回的是对象类型的指针,类型严格与对象匹配,不需要再对其进行类型转化。而malloc内存分配成功则是返回void*,需要对其进行强制类型转换,成为我们需要的返回类型。

3,内存申请失败时的返回值
new在内存申请失败后会抛出bad_alloc异常,不会返回NULL;malloc内存申请失败则会返回NULL。

C语言中,我们通常会这样做:

int *p=(int*)malloc(sizeof(int)*100);ifNULL == p){    //错误处理代码}else{}

而在C++中,这样做是没有意义的,C++正确的做法是使用异常机制:

try{  int *p = new int();}catch(bad_malloc){//处理方式}

4,是否需要指定内存大小
使用new操作符申请内存分配时无需指定内存块的大小,编译器会根据类型自行计算,而malloc则需要显式地指出内存大小。

5,是否调用构造函数、析构函数
使用new操作符会经历以下步骤:
(1),调用operator new函数(对于数组是operator new[])分配一块足够大的原始的内存空间以便于存储特定类型的对象。
(2),编译器运行响应的 构造函数以构造对象为其传入初值。
(3),对象构造完成后,返回一个指向该对象的指针。

使用delete操作符来释放对象内存时会经历两个步骤:
(1),调用对象的析构函数
(2),编译器调用operator delete(或operator delete[])函数释放内存空间。
而malloc/free不会调用构造函数和析构函数。

6,对数组的处理
C++提供了new[]与delete[]来专门处理数组类型。它会分别调用构造函数初始化每一个数组元素,释放对象时为每个对象调用构造函数。而malloc申请内存时,需要手动自定数组的大小。注意:malloc/free,new/delete,new[]/delete[]都需要匹配使用,不然会造成内存泄漏。

7,new与malloc是否可以相互调用
operator new / operator delete的实现可以基于malloc,而malloc的实现不可以去调用new。

8,是否可以被重载
operator new/operator delete可以被重载。标准库定义了operator new/operator delete函数的8个重载版本。而malloc/free不允许重载。

9,重新分配内存
使用malloc分配内存后,如果在使用过程中发现内存不足,可以使用realloc函数进行内存重新分配实现内存的扩充。realloc先判断当前指针所指的内存是否有足够的连续空间,如果有,原地扩大可分配的内存地址,并且返回原来的指针地址;如果空间不够,先按照新制定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,然后释放原来的内存区域。new没有这样直观的配套设施来扩充内存。

10,客户处理内存分配不足
在operator new抛出异常以反映一个未满足的需求之前,它会先调用一个用户指定的错误处理函数,这就是new_handler。new_handler是一个指针类型,指向了一个没有参数、没有返回值的函数,客户需要调用set_new_handler,这是一个声明于标准库的函数。
set_new_hanlder的参数为new_handler指针,指向了operator new无法分配内存时该调用的函数。其返回值也是个指针,指向set_new_handler函数。
对于malloc,客户并不能去编程决定内存不足以分配时要做什么事,只能看着malloc返回NULL。

1 0