new与malloc的区别
申请的内存所在位置
- new 从自由存储区上为对象动态分配内存空间,malloc函数从堆上动态分配内存。
- 自由存储区不仅可以是堆,还可以是静态存储区,这都看operator new在哪里为对象分配内存
返回类型安全
- new操作符内存分配成功时,返回的是对象类型的指针;是类型安全的malloc内存分配成功则是返回void * ,需要通过强制类型转换将void*指针转换成我们需要的类型
- 类型安全很大程度上可以等价于内存安全,类型安全的代码不会试图方法自己没被授权的内存区域
内存分配失败时的返回值
- new内存分配失败时,会抛出bac_alloc异常;malloc分配内存失败时返回NULL
是否需要指定内存大小
- 使用new操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算,而malloc则需要显式地指出所需内存的尺寸。
是否调用构造函数/析构函数
使用new操作符来分配对象内存时会经历三个步骤:
- 调用operator new 函数(对于数组是operator new[])分配一块足够大的,原始的,未命名的内存空间以便存储特定类型的对象。
- 编译器运行相应的构造函数以构造对象,并为其传入初值。
- 对象构造完成后,返回一个指向该对象的指针。
使用delete操作符来释放对象内存时会经历两个步骤:
- 调用对象的析构函数。
- 编译器调用operator delete(或operator delete[])函数释放内存空间。
对数组的处理
- C++提供了new[]与delete[]来专门处理数组类型:使用new[]分配的内存必须使用delete[]进行释放
- 至于malloc,它并知道你在这块内存上要放的数组还是啥别的东西,反正它就给你一块原始的内存,在给你个内存的地址就完事。所以如果要动态分配一个数组的内存,还需要我们手动自定数组的大小
是否可以被重载
- opeartor new /operator delete可以被重载;而malloc/free并不允许重载
能够直观地重新分配内存
-
使用malloc分配的内存后,如果在使用过程中发现内存不足,可以使用realloc函数进行内存重新分配实现内存的扩充。realloc先判断当前的指针所指内存是否有足够的连续空间,如果有,原地扩大可分配的内存地址,并且返回原来的地址指针;如果空间不够,先按照新指定的大小分配空间,将原有数据从头到尾拷贝到新分配的内存区域,而后释放原来的内存区域。
-
new没有这样直观的配套设施来扩充内存。
总结
特征 | new/delete | malloc/free |
---|---|---|
分配内存的位置 | 自由存储区 | 堆 |
内存分配成功的返回值 | 完整类型指针 | void* |
内存分配失败的返回值 | 默认抛出异常 | 返回NULL |
分配内存的大小 | 由编译器根据类型计算得出 | 必须显式指定字节数 |
处理数组 | 有处理数组的new版本new[] | 需要用户计算数组的大小后进行内存分配 |
已分配内存的扩充 | 无法直观地处理 | 使用realloc简单完成 |
是否相互调用 | 可以,看具体的operator new/delete实现 | 不可调用new |
分配内存时内存不足 | 客户能够指定处理函数或重新制定分配器 | 无法通过用户代码进行处理 |
函数重载 | 允许 | 不允许 |
构造函数与析构函数 | 调用 | 不调用 |