【问题标题】:User-implemented memory management [closed]用户实现的内存管理[关闭]
【发布时间】:2020-04-05 02:14:39
【问题描述】:

我被分配了一个 C 项目任务,要求我实现一个简单的内存管理库。它的工作方式是它具有 init 函数,该函数将指针(void *)指向另一个 c 程序分配的内存块以及块的大小,并具有其他两个函数来从所述分配请求大小的块当传回指向它的指针时分块并释放一个块。

问题是我被要求将我的管理结构保留在块本身内,而我对如何做到这一点的想法为零。我考虑过将块划分为帧,但是如何在不使用块外部的任何内容的情况下跟踪分配了哪些帧?

编辑:初始化函数是这样使用的。有这个程序将调用我要编写的库。它将使用 malloc 或 calloc 分配一块内存。然后它将调用库中的 init 函数并将指向该内存块的指针以及块的大小传递给它。

我的库将使用该块做什么是按需分配块。所以我的库的分配函数实际上是从块中请求一块内存(大小作为参数传递)的调用。并且它会返回一个 (void *) 指向分配的内存块的指针。

Edit2:为了使情况更清楚,我的库必须能够分配和解除分配,这意味着漏洞将出现在它正在管理的块中,并且它将采用首次拟合、最佳拟合或最差拟合。

Edit3:有没有办法将内存地址转换为 long int?

【问题讨论】:

  • 这就是常见的malloc 实现的工作方式。尝试阅读它。
  • 谨慎措辞。你说“由另一个 C 程序分配的一块内存”——这在那儿很不寻常。如果另一个程序分配内存块,它必须是共享内存(或者它将是在 fork() 之前分配的内存并在exec*() 操作之前由子进程继承)。否则,您无法直接访问另一个进程分配的内存。我不确定你的意思是“其他 C 函数”还是其他东西。但是内存管理器的基本过程通常是分配大块并按需分配较小的块。
  • @Eugene Sh.我做到了。它没有帮助。
  • 您是否至少允许块外的一两个指针知道内存列表从哪里开始?我会假设是这样,但你应该仔细检查。
  • 此外,每个分配的内存块的页眉(或页脚)位于返回给用户的指针之外是一种非常常见的方法。有人想要 32 字节,你分配 sizeof(YourHeader)+32 字节,将链表设置为阻塞或其他,然后返回指向允许用户使用的区域的指针。

标签: c pointers memory-management


【解决方案1】:

以下是您需要做什么的粗略想法:

内存段的结构应该是块的链表。每个块都以您的管理结构的副本开始,然后是您分配的内存。

初始化时,将链表的头部指向给定内存段的开头。将大小设置为段的大小减去管理结构的大小,并将next指针设置为NULL。

当发出第一个分配请求时,将头块的大小设置为请求的大小,然后立即设置指向内存的下一个指针。将新块的大小设置为旧的头大小减去请求的大小和管理结构的大小。

对于解除分配,您需要先找到要释放的块。将前一个块的大小更改为已释放块的大小加上结构体大小,然后将下一个指针更改为已释放块的下一个指针。

这应该足以让你开始。

【讨论】:

  • 如何在这种结构中释放内存块或跟踪当前分配的部分?是否可以对这种结构使用最佳拟合/最差拟合方法?
  • @BerkErzin 您可以在结构中使用一个标志来说明内存是否可用或正在使用,或者您可以维护一个可用内存列表和一个已用内存列表。无论哪种情况,您都需要某种方法来整合空闲块以减少碎片。
  • 如果你想要最合适的(顺便说一句,不适合碎片化),而不是找到第一个可能适合你的记忆的空闲块,你搜索直到你找到一个完全合适的或者直到你点击空闲列表的末尾,并拥有满足您需求的最接近大小的块。
  • 最差拟合与最佳拟合相同
猜你喜欢
  • 2011-05-03
  • 1970-01-01
  • 1970-01-01
  • 2011-06-02
  • 2021-09-23
  • 1970-01-01
  • 1970-01-01
  • 2018-08-17
  • 2012-11-15
相关资源
最近更新 更多