以下内容转载自博客一和博客二
(1)malloc和new都是在堆上开辟内存的
malloc只负责开辟内存,没有初始化功能,需要用户自己初始化;new不但开辟内存,还可以进行初始化,如new int(10);表示在堆上开辟了一个4字节的int整形内存,初始值是10,再如new int[10] ();表示在堆上开辟了一个包含10个整形元素的数组,初始值都为0。
(2)malloc是函数,开辟内存需要传入字节数,如malloc(100);表示在堆上开辟了100个字节的内存,返回void*,表示分配的堆内存的起始地址,因此malloc的返回值需要强转成指定类型的地址;new是运算符,开辟内存需要指定类型,返回指定类型的地址,因此不需要进行强转。
如堆上开辟int整形:
int p1 = (int)malloc(sizeof(int));
=> 根据传入字节数开辟内存,没有初始化
int *p2 = new int(0);
=> 根据指定类型int开辟一个整形内存,初始化为0
int p3 = (int)malloc(sizeof(int)*100);
=> 开辟400个字节的内存,相当于包含100个整形元素的数组,没有初始化
int *p4 = new int100;
=> 开辟400个字节的内存,100个元素的整形数组,元素都初始化为0
(3)malloc开辟内存失败返回NULL,new开辟内存失败抛出bad_alloc类型的异常,需要捕获异常才能判断内存开辟成功或失败,new运算符其实是operator new函数的调用,它底层调用的也是malloc来开辟内存的,new它比malloc多的就是初始化功能,对于类类型来说,所谓初始化,就是调用相应的构造函数。
(4)malloc开辟的内存永远是通过free来释放的;而new单个元素内存,用的是delete,如果new[]数组,用的是delete[]来释放内存的。
详细使用规则参照我的上一篇博客 https://blog.csdn.net/weixin_39411321/article/details/89310651
(5)malloc开辟内存只有一种方式,而new有四种分别是普通的new(内存开辟失败抛出bad_alloc异常), nothrow版本的new,const new以及定位new。
注意这里 : 如果问到malloc,还有可能问你memcpy等,realloc函数能不能在C++中使用,绝对不能,因为这些函数进行的都是内存值拷贝(也就是对象的浅拷贝),会发生浅拷贝这个严重的问题!
博客二:
new和malloc的区别是C/C++一道经典的面试题,我也遇到过几次,回答的都不是很好,今天特意整理了一下。
0、属性
new/delete是C++关键字,需要编译器支持。malloc/free是库函数,需要头文件支持。
1、参数
使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。而malloc则需要显式地指出所需内存的尺寸。
2、 返回类型
new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。
3.、分配失败
new内存分配失败时,会抛出bac_alloc异常。malloc分配内存失败时返回NULL。
4. 自定义类型
new会先调用operator new函数,申请足够的内存(通常底层使用malloc实现)。然后调用类型的构造函数,初始化成员变量,最后返回自定义类型指针。delete先调用析构函数,然后调用operator delete函数释放内存(通常底层使用free实现)。
malloc/free是库函数,只能动态的申请和释放内存,无法强制要求其做自定义类型对象构造和析构工作。
5. 重载
C++允许重载new/delete操作符,特别的,布局new的就不需要为对象分配内存,而是指定了一个地址作为内存起始区域,new在这段内存上为对象调用构造函数完成初始化工作,并返回此地址。而malloc不允许重载。
6. 内存区域
new操作符从自由存储区(free store)上为对象动态分配内存空间,而malloc函数从堆上动态分配内存。自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。自由存储区不等于堆,如上所述,布局new就可以不位于堆中。