malloc如何在细节上工作?

时间:2015-03-25 04:48:24

标签: memory malloc

我试图找到关于malloc函数的一些有用信息。 当我调用此函数时,它会动态分配内存。它将指针(例如地址)返回到分配的存储器的开头。 问题:

  • 如何使用返回的地址来读/写分配的内存块(使用不正确的寻址寄存器或如何?)

  • 如果无法分配内存块,则返回NULL。什么是硬件方面的NULL?

  • 为了在堆中分配内存,我们需要知道哪些内存部分被占用。存储此信息(关于占用的内存)(例如,我们使用小型risc微控制器)?

2 个答案:

答案 0 :(得分:0)

Q3管理堆的常用方法是通过链表。在最简单的情况下,malloc函数保留指向堆中第一个自由空间块的指针,每个自由空间块都有一个标题指向堆中的下一个空闲空间块。所以堆是有效的自我定义,知道什么是没有被占用(并通过推断因此被占用);这最小化了管理堆所需的开销RAM量。

当通过malloc调用需要新空间时,通过遍历链表找到足够大的可用空间块。发现自由空间块被赋予malloc调用者(带有一个小的隐藏头),如果需要,一个较小的自由空间块被插入到链表中,原始空闲块之间的任何剩余空间和多少内存malloc电话要求。

当应用程序释放堆块时,其块只是使用链表头格式化,并添加到链表中,通常还有一些额外的逻辑将连续的自由空间块组合成一个更大的自由空间块。

malloc的调试版本通常做得更多,包括保留已分配区域的链接列表,"保护区域"在分配的堆区域周围,以帮助检测内存溢出等。这些占用额外的堆空间(使堆在应用程序的可用空间方面实际上更小),但在调试时非常有用。

Q2 NULL指针实际上只是一个零,如果使用它,则尝试从RAM的位置0开始访问存储器,这几乎总是保留OS的存储器。这是导致大量内存违规中止的原因,所有这些都是由程序员缺乏对分配内存的函数返回NULL的错误检查引起的。

由于非OS应用程序访问内存位置0绝不是您想要的,因此大多数硬件都会中止非OS软件访问位置0的任何尝试。即使使用页面映射使得应用程序内存空间(包括位置0)永远不会映射到实际RAM位置0,因为NULL始终为零,所以大多数CPU仍将中止尝试访问位置0,前提是这是通过包含NULL的指针。

鉴于您的RISC处理器,您需要阅读其文档以了解它如何处理访问内存位置0的尝试。

Q1有许多高级语言方法可以使用分配的内存,主要是通过指针,字符串和数组。

就汇编语言和硬件本身而言,分配的堆块地址只是被放入一个用于内存间接的寄存器中。您需要了解RISC处理器中的处理方式。但是,如果您使用C或C ++或更高级别的语言,那么您不必担心寄存器;编译器处理所有这些。

答案 1 :(得分:-1)

由于您使用的是malloc,我们可以假设您使用的是C吗? 如果是,则将结果分配给指针变量,然后可以通过引用变量来访问内存。你真的不知道如何在汇编中实现它。这取决于您使用的CPU。 malloc如果失败则返回0。由于通常将NULL定义为0,因此可以测试NULL。你不关心malloc如何跟踪空闲内存。如果您真的需要这些信息,您应该查看网上提供的glibc / malloc中的来源

char * c = malloc(10);   // allocate 10 bytes
if (c == NULL)
   // handle error case
else
   *c = 'a'  // write a in the first character on the block