2012-02-17 207 views
8

该查询涉及使用malloc分配内存。在没有操作系统的嵌入式系统中的malloc

通常我们说的是malloc从堆中分配内存。

现在说我有一个普通的嵌入式系统(无操作系统),我有正常的程序加载我在我的程序中做的malloc

在这种情况下,从哪里分配内存?

回答

8

malloc()是一个通常由运行时库实现的函数。你是对的,如果你在一个操作系统上运行,那么malloc有时(但不是每次)都会触发一个系统调用,这会使操作系统将一些内存映射到程序的地址空间。

如果您的程序在没有操作系统的情况下运行,那么您可以将您的程序看作的操作系统。您可以访问所有地址,这意味着您可以将一个地址分配给一个指针,然后将该指针取消引用为读/写。

当然,你必须确保你的程序中没有其他部分只是使用相同的内存,让你写你自己的内存管理器:

简单地说,你可以提留一个地址范围你的“内存管理器”用来存储哪些地址范围已被使用(存储在那里的数据结构可以像链表一样简单或复杂得多)。然后你会写一个函数,并把它称为例如malloc()它构成了你的内存管理器的功能部分。它会查看所提到的数据结构,以查找只要参数指定并返回指向它的指针的范围地址。

现在,如果程序中的每个函数调用malloc(),而不是随机写入自定义地址,则您已完成第一步。你可以写一个免费()函数,它会查找它在上述数据结构中给出的指针,并调整数据结构(在天真的链表中它会合并两个链接)。

+1

没有回答真正的问题:动态分配的内存在哪里去。它去堆。堆在哪里?它位于由链接器脚本配置的地址范围内。 – 2013-12-24 17:01:33

+0

@fanl你的问题不同于梅西的问题。你答应了这个答案吗?请撤消。如果你打开自己的问题,我会尽力回答。 – 2013-12-26 11:26:43

5

唯一真正的答案是“无论你的编译器/库实现如何”。

在我使用的嵌入式系统中,没有堆,因为我们没有写入。

+0

+1并且当您启用优化时,编译器可以在它确定分配是本地分配(例如,函数)时选择堆栈。 – justin 2012-02-17 20:35:36

+0

好吧,真的,但也不是很有帮助。 – 2012-12-29 21:34:15

4

从你说的堆里出来。不同之处在于堆不是由OS提供的。无疑,应用程序的链接器脚本中会包含堆的分配。运行时库将管理这个。

对于Newlib C库,通常在基于GCC的嵌入式系统中不使用OS或至少不运行Linux的情况下,该库有一个存根syscall函数sbrk()。开发人员可以使用sbrk()来实现这个功能,它必须根据请求为堆管理器提供更多的内存。通常它只增加一个指针并返回一个指向新块开始的指针,此后库的堆管理器管理并维护可能与之前块相邻或不相邻的新块。上一个链接包含一个示例实现。