使用malloc和new是由于为了节约内存,很多数据都是动态生成的。
1.malloc函数
如下是分配长度为100个字节的内存块,返回值为void* ,表示未确定类型的指针。因此往往需要加上强制转换,如下所示,malloc和free一起使用。
char *p;
p=(char *)malloc(100); //分配成功则返回分配后内存空间的首地址,不成功则返回空指针null
1.1malloc函数实现原理:
1)malloc 函数的实质是它有一个将可用的内存块连接为一个长长的列表的所谓空闲链表。
2)调用 malloc(n)函数时,它沿着连接表寻找一个大到足以满足用户请求所需要的内存块。 然后,将该内存块一分为二(一块的大小与用户申请的大小相等,另一块的大小就是剩下来的字节)。 接下来,将分配给用户的那块内存存储区域传给用户,并将剩下的那块(如果有的话)返回到连接表上。
3)调用 free 函数时,它将用户释放的内存块连接到空闲链表上。
4)到最后,空闲链会被切成很多的小内存片段,如果这时用户申请一个大的内存片段, 那么空闲链表上可能没有可以满足用户要求的片段了。于是,malloc()函数请求延时,并开始在空闲链表上检查各内存片段,对它们进行内存整理,将相邻的小空闲块合并成较大的内存块。
1.2为什么会大于请求长度n是由于:需要内存对齐
如某个机器的整型长度为4个字节且它的起始存储位置能够被4整除,那么结构体
struct ALLGN {
char a;
int b;
char c;
};
实际申请内存大小要为4的整数倍,因此该结构体所占大小为12字节,实际只使用到6个字节
内存对齐详见:https://blog.csdn.net/misskissc/article/details/14647845
2.new函数
和上述一样也是动态分配堆内存,new和/delete一起使用
new用法
//开辟单地址空间
int *p = new int; //开辟大小为sizeof(int)空间
int *q = new int(5); //开辟大小为sizeof(int)的空间,并初始化为5。
//开辟数组空间
//一维
int *a = new int[100]{0};//开辟大小为100的整型数组空间,并初始化为0。
//二维
int (*a)[6] = new int[5][6];
//三维
int (*a)[5][6] = new int[3][5][6]
delete用法
//释放单个int空间
int *a = new int;
delete a;
//释放int数组空间
int *b = new int[5];
3.malloc/free和new/delete的区别
(1)属性
malloc/free是C/C++库函数,需要头文件支持。new/delete是关键字,需要编译器支持。
(2)内存区域
new/delete不仅会分配内存,还会自动调用构造和析构函数,而malloc和free只会分配内存。
(3)参数
new申请无需指定内存大小,而malloc需指定内存
(4)返回类型不一样
new返回的是对象类型的指针,如int *p = new int;返回的就是一个int型指针。
而malloc返回的是*void,即无类型的指针,需做强制性转化,见上第一个例子。
(5)重载
C++允许重载new/delete操作符,malloc不允许重载
(6)分配失败
new分配失败,会爆出bac_alloc异常,malloc分配异常返回null
(7)内存泄漏
内存泄漏对于new/delete都能检测出来,而new可以指明是文件的哪一行。而malloc不可以。
Reference :