0

0

实现 malloc() 和 free() — 将元数据添加到内存块

WBOY

WBOY

发布时间:2024-07-10 08:46:01

|

282人浏览过

|

来源于dev.to

转载

实现 malloc() 和 free() — 将元数据添加到内存块

这篇文章是关于实现 malloc() 和 free() 函数的系列文章的一部分。之前,我们实现了一种相当简单的方法,几乎​​不释放任何内存:一个指针指向最后分配的块,使 free() 能够释放它,但只能释放它。

更好的选择是让最后一个块指向倒数第二个块,倒数第二个块指向倒数第三个块,依此类推,形成一个链表。为了实现这一点,我们创建一个结构体作为块的标题,其中包含指向前一个块的指针:

typedef 结构头 {
  结构头*前一个;
标题;

此外,指向最后一个块的指针,以前是 void*,现在是 Header* 类型:

标题*最后= NULL;

为了使用这些标头,abmalloc() 会保留足够的内存来存储标头和请求的大小:

void *abmalloc(size_t 大小) {
  标头 *header = sbrk(sizeof(标头) + 大小);

通过这种方式,我们使用块的开头来存储必要的信息,例如指向新块之前最后分配的块的指针:

 标题->上一个 = 最后一个;

然后,我们更新最后一个指向新区块:

 最后 = 标题;

最后,我们返回一个指向用户可以使用的内存的指针。由于 header 指向元数据,我们不能简单地返回它。否则,当用户使用指针时,所有头信息都会被覆盖!相反,我们返回一个指向标题后面的指针。这个指针很容易计算:它是 header 的内存地址加上 header 的大小:

谷歌AI
谷歌AI

Google AI Tools for everyone

下载
 返回标头 + 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() — 将元数据添加到暂停怀疑中的内存块。”

相关专题

更多
golang结构体相关大全
golang结构体相关大全

本专题整合了golang结构体相关大全,想了解更多内容,请阅读专题下面的文章。

196

2025.06.09

golang结构体方法
golang结构体方法

本专题整合了golang结构体相关内容,请阅读专题下面的文章了解更多。

189

2025.07.04

javascriptvoid(o)怎么解决
javascriptvoid(o)怎么解决

javascriptvoid(o)的解决办法:1、检查语法错误;2、确保正确的执行环境;3、检查其他代码的冲突;4、使用事件委托;5、使用其他绑定方式;6、检查外部资源等等。本专题为大家提供相关的文章、下载、课程内容,供大家免费下载体验。

175

2023.11.23

java中void的含义
java中void的含义

本专题整合了Java中void的相关内容,阅读专题下面的文章了解更多详细内容。

97

2025.11.27

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

392

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

572

2023.08.10

堆和栈的区别
堆和栈的区别

堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

392

2023.07.18

堆和栈区别
堆和栈区别

堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

572

2023.08.10

PHP WebSocket 实时通信开发
PHP WebSocket 实时通信开发

本专题系统讲解 PHP 在实时通信与长连接场景中的应用实践,涵盖 WebSocket 协议原理、服务端连接管理、消息推送机制、心跳检测、断线重连以及与前端的实时交互实现。通过聊天系统、实时通知等案例,帮助开发者掌握 使用 PHP 构建实时通信与推送服务的完整开发流程,适用于即时消息与高互动性应用场景。

3

2026.01.19

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号