2024年3月25日 八股
new、delete和malloc、free区别
-
new 和 delete 是C++的操作符,而 malloc 和 free 是C语言的库函数
-
new 会调用构造函数(同理 delete 会调用析构函数),而 malloc 和 free 不会
-
new返回的是对象的指针,而malloc返回的是 void* 类型(泛型指针)
-
new操作符申请内存分配时不需要指定内存大小,而 malloc 需要显示的指出所需内存的大小
-
new分配内存失败时,会抛出 bac_alloc 异常,而 malloc 会返回 NULL
new操作符抛出异常代码如下:
try{
int *a = new int();
}catch(bad_alloc){
...
}
-
new申请内存时从自由存储区为对象分配,而 malloc 从堆区分配
-
new是一个操作符,可以进行重载,而 malloc 不行
-
new 是类型安全的,malloc 不是(malloc 返回的是一个 void* 类型,需要进行强制类型转换)
关系:new封装了malloc
用 new 创建对象时,首先从堆中申请相应的内存空间,然后调用对象的构造函数,最后返回指向对象的指针。new 操作符从自由存储区(free store)上为对象动态分配内存空间,而 malloc 函数从堆上动态分配内存。
自由存储区是 C++ 基于 new 操作符的一个抽象概念,凡是通过 new 操作符进行内存申请,该内存即为自由存储区。
而堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分配,
C 语言使用 malloc 从堆上分配内存,使用 free 释放已分配的对应内存。new 可以指定在内存地址空间创建对象。
执⾏ new 实际上执⾏两个过程:1.分配未初始化的内存空间(malloc);2.使⽤对象的构造 函数对空间进⾏初始化;返回空间的⾸地址。如果在第⼀步分配空间中出现问题,则抛出 std::bad_alloc 异常,或被某个设定的异常处理函数捕获处理;如果在第⼆步构造对象时出现 异常,则⾃动调⽤ delete 释放内存。 执⾏ delete 实际上也有两个过程:1. 使⽤析构函数对对象进⾏析构;2.回收内存空间 (free)。
new 与 delete 必须配套使用,new[ ]和delete[ ]必须配套使用, malloc 和 free 必须配套使用
new和delete主要是为了为那些自定义类型的对象开辟空间,因为这些对象在创建的时候要自动执行构造函数,消亡的时候要执行析构函数,对于自定义类型对象如果不配对使用的话,可能会出现没有析构干净的情况
delete 只调用一次析构函数,而delete[ ] 会调用多次
如果用free 释放 “new 创建的动态对象”,那么该对象因无法执行析构函数而可能导致程序出错。如果用delete 释放“malloc 申请的动态内存”,理论上讲程序不会出错,但是该程序的可读性很差。所以new/delete 必须配对使用,malloc/free 也一样
有了malloc/free为什么还要new/delete?
对于一些非内部数据类型来说(类对象),我们在对象创建的同时需要自动调用构造函数进行初始化,在对象消亡的时候需要自动调用析构函数去释放其资源,而 malloc 和 free 并不具备这种功能(是库函数⽽不是运算符,不在编译器控制权限之内),这个时候就需要用到 new 和 delete 了 。
既然new/delete 的功能完全覆盖了malloc/free,为什么C++不把malloc/free 淘汰出局呢?
虽然 new 和 delete 已经完全具备了 malloc 和 free 的特性,但是 malloc 和 free 还是必须的,因为在C++程序中会经常用到C语言的代码,而C语言只能用 malloc 和 free 动态管理内存。