本文是关于实现的 malloc() 和 free() 函数系列文章的一部分。在此之前,我们实现了一个非常简单的方法,几乎没有释放任何内存:指针指向最终分配的块,以便 free() 它可以释放,但只能释放。
更好的选择是让最后一块指向倒数第二块,倒数第二块指向倒数第三块,等等,形成链表。为了实现这一点,我们创建了一个结构作为块的标题,包括指向前一块的指针:
<a style="color:#f60; text-decoration:underline;" href="https://www.php.cn/zt/58423.html" target="_blank">typedef</a> 结构头 { 结构头*前一个; 标题;
另外,指向最后一块的指针以前是 void*,现在是 Header* 类型:
标题*最后= NULL;
使用这些标头,abmalloc() 为了存储标头和要求的大小,会保留足够的内存:
void *abmalloc(size_t 大小) { 标头 *header = sbrk(sizeof(标头) 大小);
这样,我们就可以用块的开头来存储必要的信息,比如指向新块之前最后分配的块的指针:
标题->上一个 = 最后一个;
然后我们更新最后一个指向新区块:
最后 = 标题;
最后,我们返回一个指向用户可以使用的内存的指针。因为 header 我们不能简单地返回指向元数据。否则,当用户使用指针时,所有头部信息都将被覆盖!相反,我们返回指向标题后面的指针。这个指针很容易计算:它是 header 的内存地址加上 header 的大小:
返回标头 1; }
注意我们怎么做 header 指针加 1.因为指针的类型是 Header*,所以增量实际上是 Header 结构体的字节数,而不仅仅是一个字节。指针类型与指针操作密切相关。
现在我们的内存块从一开始就有元数据,我们在释放时需要考虑这一点。 free() 接收的指针不是指向块的开头,而是指向用户可用的内存。因此,我们需要从用户传输的指针中找到块。没有什么是指针算术无法解决的:
void abfree(void *ptr) { 标头 *标头 = (标头*) ptr - 1;
如果 header 指向最后分配的块,前一块将成为最后一块。在这种情况下,我们可以通过brk()将堆中的内存返回到操作系统:
if (标题==最后){ 最后=标题->上一个; brk(标头); } }
这是我们的新 malloc() 和 free() 函数:
typedef 结构头 { 结构头*前一个; 标题; 标头*最后= NULL; 无效* abmalloc(size_t大小){ 标头 *header = sbrk(sizeof(标头) 大小); 标题->最后一个=最后一个; 最后=标题; 返回标头 1; } 无效 abfree(无效 *ptr) { 标头 *标头 = (标头*) ptr - 1; 假如(标题==最后){ 最后=标题->上一个; brk(标头); } }
abmalloc() 和 abfree() 现在可能会稍微提高内存效率,但也不会高很多。动态内存很少像堆栈一样工作,最旧的块总是先释放。在下一篇文章中,我们将看到如何使用不再使用的旧块的内存。
(本文最初发表为“实现” malloc() 和 free() — 添加元数据暂停怀疑中间的内存块。"
以上就是实现 malloc() 和 free() — 将元数据添加到内存块的详细内容中,请关注其他相关文章!
实现 malloc() 和 free() — 将元数据添加到内存块中-C
高效稳定,选择专业服务器托管服务
照片复制粘贴失效?轻松解决,一键搞定!
整数溢出-C
自建服务器,掌控未来,高效稳定,尽在掌握!
理解复制到剪贴板:高效数据传递的秘诀
踏上为期一年的软件工程之旅:从 C 到 Python、JavaScript、Node.js、DevOps 等-C
整数溢出-C
踏上为期一年的软件工程之旅:从 C 到 Python、JavaScript、Node.js、DevOps 等-C
《王者荣耀》元流之子上线时间介绍-手机游戏策略
“最强祖师”升级专业技能道具介绍-手机游戏策略
最强祖师后勤弟子招募策略-手机游戏策略
南宫婉最强祖师的技能强度和玩法策略-手机游戏策略
“绝区零”体力使用策略-手机游戏策略
阴阳师禅心云外镜新皮肤获取策略-手机游戏策略
如何抗腐蚀不朽之旅 《不朽之旅》腐化装备保障机制介绍-手机游戏策略
《地下城与勇士:起源》女鬼剑上线时间详解-手机游戏策略
《绝区零》加好友的具体步骤-手机游戏策略
《未定事件簿》四周年福利活动介绍-手机游戏策略