首先说一下三种new
A.new operator, delete operator : 申请内存+构造函数
B.new[], delete[] : 用于数组类的操作
C.placement new : 定点new,它用于在给定的内存中初始化对象,也就是说你手中已有一块闲置的内存,例如:void* buffer = operator new(sizeof(string));//那么现在buffer是你所拥有闲置内存的指针buffer = new(buffer) string(“abc”); //调用了placement new,在buffer所指向的内存中初始化string类型的对象,初始值是"abc"
new和malloc的区别
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 int[100] (); => 开辟 400 个字节的内存,100 个元素的整形数组,元素都初始化为 0
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。
dlete和free的区别
free是C的库函数,delete是一个运算符的重载函数operator delete
free只能释放内存,而delete会先析构,再释放内存(free)
free不区分单个元素和数组内存释放;而delete需要区分,因为单个元素和数组元素调用的析构函
数是不一样多的
new和delete
- new 的底层也是通过 malloc 来开辟内存的,new 比 malloc 多一项功能,就是开辟完内存,还可以进行初始化操作,如下:
int *p = new int(10);上面是 new 的基本操作,10 代表堆上开辟的整形内存的初始值;如果是自定义类类型的话,如下:Test *p = new Test();这个语句不仅会在堆上开辟 Test 类型大小的一块内存;还会调用 Test 类的默认构造函数构造一个对象出来,这些都是 malloc 办不到的!
2)delete 比 free 多一项功能就是在释放内存之前,还可以析构指针指向的对象,new 和delete 配对使用,new[]和 delete[]配对使用,尽量不要交叉使用,以免产生不可预期的问题。
3)new 开辟内存失败是抛出 bad_alloc 类型的异常,因此代码上要捕获该类型的异常才能正确的判断堆内存是否分配成功;malloc 内存开辟失败返回的是 NULL 指针。
4)new 和 delete 不仅仅是运算符,它们实际上是运算符重载函数的调用,对应的函数名是 operator new 和 operator delete,可以在全局或者类的作用域中提供自定义的 new 和delete 运算符的重载函数,以改变默认的 malloc 和 free 内存开辟释放行为,比如说实现内存池。