malloc()函数用于动态分配内存空间。其原型为:void*malloc(size_tsize);
说明:
【参数说明】
Size为要分配的内存空间的大小,并以字节为单位。
【函数说明】
Malloc()在堆区中分配指定大小的内存空间来存储数据。该内存空间在函数执行完成后不会被初始化,其值是未知的。如果要在分配内存时对其进行格式化,请使用calloc()()函数。
【返回值】
分配成功则返回指向内存的地址,分配失败则返回NULL。
运行:
由于申请时内存空间可能可用,也可能不可用,所以在进行后续操作之前需要判断申请是否成功。
如果大小值为0,则返回值将根据标准库实现的不同而有所不同,可能为空,也可能不为空,但返回的指针不应被再次引用。
注意:函数的返回值类型为void*。void并不是指没有返回值或者返回空指针,而是指返回的指针类型未知。因此,在使用malloc()时,我们通常需要进行强制类型转换,将void指针转换为我们想要的类型,例如:
#include
typedefintListData;
ListData*data;//存储空间基址
data=(ListData*)malloc(100*sizeof(ListData));
扩展信息
malloc的实现方式:
(1)数据结构
首先我们要定义所使用的数据结构。一个简单且可能的解决方案是将堆内存空间组织成块。每个块由标识区和数据区组成,数据区记录了数据块的描述信息(数据区的大小、空闲标志位)。、指标等)。
数据区是实际分配的内存区域,数据区第一个字节的地址是malloc返回的地址。
(2)找到正确的区块
现在想想如何在区块链中找到正确的区块。一般有两种搜索算法:
Firstfit:从头开始,使用数据区大小大于所需大小的第一个块,这个自定义块称为
Bestfit:从头开始,并遍历所有块,将数据区大小大于大小且差值最小的块作为分配块
两种方法各有优点,bestfit内存占用较高(负载较高),且firstfit运行效率高。这里我们使用firstfit算法。
(3)打开新块
如果现有块不满足大小要求,则需要在链表末尾打开新块。
(4)分割块
Firstfit有一个致命的缺陷,那就是此时可能会允许较小的尺寸占用较大的块,为了增加有效负载必须将数据当区域足够大时,将其分割成新的块。
(5)Malloc实现
利用上面的代码,我们可以实现一个简单的malloc。注意,我们首先需要定义块链表的头first_block,它被初始化为NULL,另外,在执行分区操作之前,我们需要剩余空间至少为BLOCK_SIZE+8
因为我们需要通过malloc将分配的数据空间对齐8个字节,因此当大小不是8的倍数时,我们需要将大小修改为比大小大的8的最小倍数。
上一篇:malloc分配内存是堆还是栈
下一篇:malloc函数申请内存