C++: 3.new/delete和malloc/free的区别

new/delete和malloc/free的区别总结

1.本质:

malloc与free是c++/c语言的标准函数(库函数),需要头文件支持;new/delete是C++的运算符,是关键字,需要编译器支持。

2.申请的内存所在位置:

new:可以分配内存(堆、静态存储区等,取决于operator new在哪里为对象分配内存),不分配内存(定位new);
malloc: 堆上面

new操作符从自由存储区(free store)上为对象动态分配内存空间,而malloc函数从堆上动态分配内存。自由存储区是C++基于new操作符的一个抽象概念,凡是通过new操作符进行内存申请,该内存即为自由存储区。而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,C语言使用malloc从堆上分配内存,使用free释放已分配的对应内存。

那么自由存储区是否能够是堆(问题等价于new是否能在堆上动态分配内存),这取决于operator new 的实现细节。自由存储区不仅可以是堆,还可以是静态存储区,这都看operator new在哪里为对象分配内存。

特别的,new甚至可以不为对象分配内存!定位new(pleacement new)的功能可以办到这一点,定位new运算符(placement new),它能够让程序员指定要使用的位置。既将new运算符用于提供了的地址。定位new运算符在头文件中。定位new运算符直接使用传递给它的地址,它不负责判断哪些内存单元已被使用,也不查找未使用的内存块。这将一些内存管理的负担交给了程序员。以下是使用方式:

new (place_address) type

3.返回类型安全性

new操作符内存分配成功时,返回的是对象类型的指针,类型严格与对象匹配,无须进行类型转换,故new是符合类型安全性的操作符。而malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型。

4.内存分配失败时的返回值

new内存分配失败时,会返回一个异常(throw bac_alloc(" ") ),它不会返回NULL;malloc分配内存失败时返回NULL。
补充:只有nothrow new 才可以判空:
eg: int *p=new (nothrow) int (10); if (p==NULL) {return -1; }

c++ 判断内存是否开辟成功的正确的做法应该是使用异常机制:

try
{
    int *p = new int( 10 );
}
catch ( const bad_alloc)
{
    ...
}

5.是否需要指定内存大小

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

6.是否调用构造函数/析构函数

使用new操作符来分配对象内存时会经历三个步骤:
- 第一步:开辟内存:调用operator new 函数(对于数组是operator new[])分配一块足够大的,原始的,未命名的内存空间以便存储特定类型的对象。

  • 第二步:初始化:编译器运行相应的构造函数以构造对象,并为其传入初值。
  • 第三步:返回指针:对象构造完成后,返回一个指向该对象的指针。

使用delete操作符来释放对象内存时会经历两个步骤:

7.对数组的处理

new对数组的支持体现在它会分别调用构造函数函数初始化每一个数组元素,释放对象时为每个对象调用析构函数。注意delete[]要与new[]配套使用,不然会找出数组对象部分释放的现象,造成内存泄漏。至于malloc,它并知道你在这块内存上要放的数组还是啥别的东西,反正它就给你一块原始的内存,在给你个内存的地址就完事。所以如果要动态分配一个数组的内存,还需要我们手动自定数组的大小。

A * ptr = new A[10];         //分配10个A对象
delete [] ptr;               // 使用new[]分配的内存必须使用delete[]进行释放:
int * ptr = (int *) malloc( sizeof(int)*10  ); //分配一个10个int元素的数组

8.是否可以互相调用

operator new /operator delete的实现可以基于malloc,而malloc的实现不可以去调用new。new调用operator new 函数申请内存(底层是调用的malloc函数)然后调用类型的构造函数,初始化成员变量;delete会先调用析构函数,然后调用operator delete释放内存(底层:free函数)。

9.是否可以重载

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

10.扩充内存

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值