这个查询是关于使用malloc的内存分配的。
一般来说,我们所说的是malloc从堆中分配内存。
现在假设我有一个普通的嵌入式系统(没有操作系统),我已经加载了正常的程序,我在我的程序中执行malloc。
在这种情况下,内存是从哪里分配的?
发布于 2012-02-18 04:47:33
malloc()是一个通常由运行时库实现的函数。您是对的,如果您在操作系统上运行,那么malloc有时(但不是每次)都会触发系统调用,使操作系统将一些内存映射到您的程序的地址空间。
如果您的程序在没有操作系统的情况下运行,那么您可以将您的程序看作是对操作系统的。您可以访问所有地址,这意味着您只需将一个地址分配给一个指针,然后将该指针解除引用为读/写。
当然,您必须确保程序的其他部分不使用相同的内存,因此您编写了自己的内存管理器:
简单地说,您可以留出一个地址范围,供"memory-manager"用来存储已在使用的地址范围(存储在其中的数据结构可以像链表一样简单,也可以复杂得多)。然后,您将编写一个函数并调用它,例如,malloc(),它构成了内存管理器的函数部分。它查看前面提到的数据结构,以找到与参数指定的长度相同的范围地址,并返回指向该地址的指针。
现在,如果程序中的每个函数都调用malloc(),而不是随机写入自定义地址,那么您已经完成了第一步。您可以编写一个free()-function,它将查找在上述数据结构中给出的指针,并调整数据结构(在朴素的链表中,它将合并两个链接)。
发布于 2012-02-18 04:33:51
唯一真正的答案是“你的编译器/库实现把它放在哪里”。
在我使用的嵌入式系统中,没有堆,因为我们还没有编写一个堆。
发布于 2012-02-18 06:16:07
就像你说的那样。区别在于堆不是由操作系统提供的。毫无疑问,您的应用程序的链接器脚本将包含堆的分配。运行时库将对此进行管理。
在不运行操作系统或至少不运行Newlib的基于GCC的嵌入式系统中经常使用的sbrk C库的情况下,该库具有名为sbrk()的存根syscall函数。实现sbrk()是开发人员的责任,它必须根据堆管理器的请求提供更多的内存。通常,它只是递增一个指针并返回一个指向新块开始的指针,此后,库的堆管理器管理和维护新块,该新块可能与先前的块相邻,也可能不相邻。前面的链接包含一个示例实现。
https://stackoverflow.com/questions/9334957
复制相似问题