实现 malloc() 和 free() — 进一步减少堆

实现 malloc() 和 free() — 进一步减少堆

这篇文章是关于实现 malloc() 和 free() 函数的系列文章的一部分。在上一篇文章中,我们学习了如何重用内存块。这是一个重大进步,但还有更多改进空间。

一个例子是减小堆的大小,如第一篇文章中所述。当我们释放最后一个内存块时,我们将堆顶部移动到前一个块的末尾。然而,前一个块以及其他块也可能是免费的。考虑以下场景:

void *ptr1 = abmalloc(8);无效 *ptr2 = abmalloc(8);abfree(ptr1);abfree(ptr2);

登录后复制

在这种情况下,当我们释放 ptr2 指向的块时,我们使 ptr1 成为最后一个块。然而,ptr1也是免费的,所以我们可以进一步减小堆大小。

为了实现这一点,我们将从列表末尾开始迭代指针,直到没有更多的空闲块。如果接收到的指针的标头指向最后一个块并且前一个块是空闲的,我们将标头指针移动到它。我们重复这个过程,直到到达一个可用块,该块的前一个块正在使用中(如果是第一个块,则为 NULL)。然后,我们执行堆缩减过程:

if(标题==最后){  while ((标题->上一个!= NULL) && 标题->上一个->可用) {    标题=标题->上一页;  }  最后=标题->上一个;  brk(标头);} 别的 {

登录后复制

现在,我们需要修复 abfree() 中的一个错误。根据规范,free() 函数应该接受空指针并且不执行任何操作。然而,如果 abfree() 接收到 NULL,我们就会出现分段错误!幸运的是,通过在函数开头添加检查很容易修复:

void abfree(void *ptr) {   如果(ptr == NULL){     返回;   }   标头 *标头 = (标头*) ptr - 1;

登录后复制

所以,这是我们现在的 abfree() 函数:

void abfree(void *ptr) {   如果(ptr == NULL){     返回;   }   标头 *标头 = (标头*) ptr - 1;   如果(标题==最后){     while ((标题->上一个!= NULL) && 标题->上一个->可用) {       标题=标题->上一页;     }     最后=标题->上一个;     brk(标头);   } 别的 {     标头->可用= true;   } }

登录后复制

减少堆的大小是一个简单的优化,但仍然存在挑战。在下一篇文章中,我们将讨论如何避免为小请求重复使用非常大的内存块。

(这篇文章是 Implementando malloc() e free() — reduzindo ainda mais o heap 的翻译,首次发表于 Suspensão de Descrença。)

以上就是实现 malloc() 和 free() — 进一步减少堆的详细内容,更多请关注【创想鸟】其它相关文章!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至253000106@qq.com举报,一经查实,本站将立刻删除。

发布者:PHP中文网,转转请注明出处:https://www.chuangxiangniao.com/p/2557525.html

(0)
上一篇 2025年3月6日 08:00:54
下一篇 2025年3月6日 08:01:05

AD推荐 黄金广告位招租... 更多推荐

相关推荐

  • Guts:小型轻量级代码控制系统。

    胆量 隆重推出 Guts,一个用于管理和创建代码存储库的简单工具。这本质上是 git 的一个较小版本,我目前正在为我就读的学校的网络安全课程进行编程。 Guts 是用 C 编写的,其中包含一些额外的 bash 脚本来帮助安装和更新。 你可以…

    2025年3月6日
    000
  • 实现 malloc() 和 free() — 将元数据添加到内存块

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

    2025年3月6日
    200
  • 整数溢出

    整数溢出 整数溢出是当我们对整数的最大大小有限制并且我们的结果超过该最大大小时发生的问题,让我以基数 10 进行演示。 假设我们最多有 3 个以 10 为基数的数字,所以我们可以得到的最大值是 999,但是让我们尝试超越限制并通过在 999…

    2025年3月6日
    200
  • 踏上为期一年的软件工程之旅:从 C 到 Python、JavaScript、Node.js、DevOps 等

    踏上为期一年的软件工程之旅:从 C 到 Python、JavaScript、Node.js、DevOps 等 欢迎各位编码爱好者,踏上广阔而动态的软件工程领域的激动人心的旅程!在接下来的 365 天里,我们将踏上一场变革性的冒险之旅,穿越 …

    2025年3月6日
    200
  • 火箭池:彻底改变去中心化质押

    在不断发展的去中心化金融 (DeFi) 领域,Rocket Pool 作为一个先锋平台脱颖而出,旨在使以太坊 2.0 质押变得更容易、更安全、更有利可图。本文探讨了 Rocket Pool 项目、其功能、优势以及如何通过质押最大化收益。 什…

    2025年3月6日
    200
  • 像专业人士一样使用 XOR 在 C 中无需临时变量即可交换数字。

    在不使用临时变量的情况下交换两个变量的值是一个经典的编程问题。在 C 语言中解决这个问题的一个优雅的解决方案是使用按位异或运算。 算法 考虑两个变量 a 和 b。目标是交换他们的价值观。 用要交换的值初始化a和b。 执行以下步骤: a^=b…

    2025年3月6日
    200
  • 对 [T]csh 的修改

    我对 [T]csh 进行了一些修改。 函数(仅适用于脚本)将文件读入变量互动环节评论判断stdin是否为空 如有任何反馈、建议或贡献,我将不胜感激。非常欢迎任何形式的贡献。 一位关键的 [T]csh 开发人员要求我为我的函数发明创建文档和测…

    2025年3月6日
    200
  • C 中的可变参数函数

    介绍 C 始终使用可以接受不同数量参数的函数 – variadic++ 函数 – printf() 是主要示例。最初,C 无法让您可移植地实现自己的可变参数函数。 当函数原型从 C++ 向后移植到 C 时,它包含声明…

    2025年3月6日
    200
  • 掌握 C 编程中的多线程:深入讲解和高级概念

    介绍: C 编程中的多线程使开发人员能够充分利用现代多核处理器的潜力,促进单个进程中任务的并发执行。本综合指南探讨了基本的多线程概念、同步机制和高级主题,为每个概念提供了详细的解释和示例代码。 1. 理解线程: 线程是进程内独立的执行序列,…

    2025年3月6日
    200
  • 使用 typedef

    typedef 是我永远无法回头的事情之一。本质上,它允许对 C 中的现有类型进行别名,并使代码更易于阅读和编写。 以下例为例 struct my_struct { 整数a; 字符b;}void init_my_struct(struct …

    2025年3月6日
    200

发表回复

登录后才能评论