new和delete与malloc和free的区别
1、malloc
和free
是C语言的标准库函数;new
和delete
是C++中的操作运算符。以上两种方式均可以实现对象在堆中分配空间和回收,那么就引出了一个用谁问题:【效率层面考虑】在使用函数时,就会有函数的调用消耗,而使用操作算符不会涉及到函数消耗的问题,所以在这一点上,建议使用new
和delete
实现分配和回收。
2、使用new
操作运算符实例化对象时,它是可以自动为我们计算和分配内存空间的。如下:new
自动为a
所指对象在堆中申请了12个字节。「1个int占4个字节,需要3个int对象,即3乘4=12字节」。中括号内的3告诉new
操作符:“我需要3个对象”。接下来在初始时化时,该操作符便会通过计算预留给a
所指对象所需要的堆空间。
int* a = new int[3];
相比之下,malloc
函数需要我们事先计算出在堆中所需要的字节数。再加上需要引用一些include
包,个人认为写起来较为麻烦。另外,malloc
的返回值为void*
,在本案例中,我们需要强制其为int*
才算成功在堆中分配空间。相反地,使用new
实现对象的实例化就不需要强制转换数据类型,等号左边赋予什么类型,等号右边就new出什么类型,非常方便。
# include "Cstdlib"
# include "Cstring"
int* b = (int*)(malloc(12)); // 为指针b所指对象在堆中开辟12个字节的空间
总结本条:从【编写复杂度】的角度来看,个人还是推荐使用new
和delete
这两个操作符来实现分配和回收。
3、new
是类型安全的。如下:等号左边的类型为int*
,右边为float*
。编译器会查验出并报错。所以说是类型安全的。
int* p = new float[2];
// Cannot initialize a variable of type 'int *' with an rvalue of type 'float *'
malloc
不是类型安全的。如下:虽然笔者这样写,编译器报错了。但是对有些老的编译器来说,无法指出这种错误。所以在这里作为一个提示。
int* p = malloc(10);
// error: cannot initialize a variable of type 'int *' with an rvalue of type 'void *'
4、new
可以调用构造函数,malloc
却不能。delete
可以调用析构函数,free
却不能。那么构造对象时,没有构造函数的话,我们就无法初始化成员变量了。再有:无法调用析构函数,就无法将对象中申请的堆空间进行释放,从而会有风险导致内存的泄漏!!!
5、由于new
和delete
是操作运算符,所以可以重载,而malloc
和free
作为函数不可以重载。
小结
综上,不难看出在c++中,new
和delete
的优势要高于malloc
和free
,一般我们也主要使用前者。但个人认为,存在即合理。后者的存在一定也有它存在的意义。在遇到后者相关使用优势后,笔者会进一步探索其中的用法予以总结和分享。