【随笔记】new和malloc的区别
随笔记系列是记录一些偶然看见或被问到的一些印象深刻或经典的面试题,既然不聪明,那就只能靠积累,勤能补拙。如果有错误的地方,还请指出,谢谢!!!
前言
前两天,我的老大临时抽查了一下我“new和malloc的区别,给你20秒”,我“… …(20秒)”,“你挂了”。
说实话,malloc我就不知道是个啥,而且,对于new,我除了知道它可以用来实例化,我也没有了解过它具体是什么,就是“知其然,不知其所以然”。
痛定思痛后,我觉得开启这个【随笔记】系列,及时整理老大提出的问题,扩充自己的知识体系。下面,让我们言归正传!
一、什么是malloc?
malloc 的全称是 memory allocation(动态内存分配),用于申请一块连续的指定大小的内存块区域,以 void* 类型返回分配的内存区域地址。如果分配成功,则返回指向被分配内存的指针,否则返回空指针NULL,当内存不在使用时,应使用free()函数将内存块释放。
malloc 函数的实质体现在,它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表的功能,调用 malloc 函数时,它沿连接表寻找一个大到足以满足用户请求所需要的内存块,然后将该内存块一分为二,一块的大小与用户请求的大小相等,另一块的大小就是剩下的。调用 free 函数时,会将用户释放的内存块连接到空闲链上,当 malloc 函数请求延时,就会在空闲链上整理内存片段合成较大的内存块,如果无法获得满足要求的内存块,malloc 就会返回NULL指针。
二、什么是new?
new 的作用也是动态分配内存,如果申请成功,就会返回该内存块的首地址,否则返回零值,new 开辟的空间存储在堆上,而我们定义的变量存储在栈上,new返回的是一个指向所分配类型变量(对象)的指针,对创建的对象也是通过该指针来间接操作的。
三、new 与 malloc 的区别
最大的区别:new 申请空间的时候会调用构造函数,malloc 不会调用。
1、属性:
- new/delete 是 C++ 关键字,需要编译器支持。
- malloc/free 是库函数,需要头文件支持。
2、参数:
- 使用 new 操作符申请内存分配时无须指定内存块的大小,编译器会根据类型信息自行计算。
- malloc 需要显示地指出所需内存的尺寸。
3、返回类型:
- new 操作符内存分配成功时,返回的是 对象类型的指针,类型严格与对象匹配,无须进行类型转换,故 new 是最符合类型安全性的操作符。
- malloc 内存分配成功则返回 void,需要通过强制类型转换将 void 指针转换成我们需要的类型。
4、分配失败:
- new 在申请空间失败后返回的错误码是bad_alloc。
- malloc 在申请空间失败后会返回NULL。
5、自定义类型:
- new 会先调用 operator new 函数,申请足够的内存(通常底层使用 malloc 实现),然后调用类型的 构造函数,初始化成员变量,最后返回自定义类型指针。
- delete 先调用析构函数,然后调用 operator delete 函数释放内存(通常底层使用 free 实现)。
6、重载:
- C++ 允许重载 new/delete 操作符,特别的,布局 new 的就不需要为对象分配内存,而是指定了一个地址作为内存起始区域,new 在这段内存上为对象调用构造函数完成初始化工作,并返回此地址。
- malloc 不允许重载。
7、内存区域:
- new 操作符从自由存储区上为对象动态分配内存空间。
- malloc 函数从堆上动态分配内存。
- 自由存储区是 C++ 基于 new 操作符的一个抽象概念,凡是通过 new 操作符进行内存申请,该内存即为自由存储区。
- 堆是操作系统中的术语,是操作系统所维护的一块特殊内存,用于程序的内存动态分布,C语言使用 malloc 从堆上分配内存,使用 free 释放已分配的对应内存。
- 自由存储区不等于堆,所以,布局 new 就可以不位于堆中。
小提一下:布局new 和 常规new,布局new需要手动调用析构函数。