在嵌入式C中使用malloc()函数

6
在嵌入式C编程语言中,malloc()在单任务嵌入式系统中有用吗?
我从事嵌入式系统工作已经0.5年了。我从未在8位控制器编程中使用过malloc()
有人能建议我在8位控制器编程中使用malloc()吗?

7
可以使用。但是,由于您在嵌入式方面已经工作了5年,您应该知道它的缺点。 - Eugene Sh.
2
当你在单任务操作系统中有所有可用的内存时,你就可以像访问所有内存一样,而不需要分配或释放它。如果你想要写入某个内存位置,只需获取它并进行写入即可。 - V. Kravchenko
3
malloc 功能虽强大,但也有代价。在长时间的执行过程中,你需要担心内存碎片和垃圾回收问题。如果能在编译时分配内存结构,将会更加清晰简明。 - infixed
2
你在8位控制器上5年从未使用过malloc,这表明你并不需要它,这在一定程度上回答了你的问题。 - Jabberwocky
1
@Lundin 它不必是“堆”本身。您可以使用静态数组表示内存池,并使用与“经典”malloc相同的语义来运行指针的“愚蠢”malloc - Eugene Sh.
显示剩余20条评论
3个回答

11
在嵌入式系统中,强烈不建议使用动态分配内存。对于关键系统的行为应该是确定性的。许多用于嵌入式固件的库和操作系统都避免使用动态分配内存。
简短地说,malloc在嵌入式系统中存在问题,请参见:malloc sins
针对关键系统标准可能禁止使用malloc作为一种不良编程实践。例如MISRA C1和MISRA C2不允许使用malloc/calloc。请参见MISRA标准:MISRA
问答:dynamic memory allocation - MISRA Bulletin Board

这样的标准从未深入探究为什么在嵌入式系统中没有意义。MISRA-C现在是一种通用的编程标准,可能在嵌入式系统分支之外使用,因此它只是说堆分配由于泄漏、分段等原因是危险的。(还要注意,有一个新的MISRA“C3”,正式名称为MISRA-C:2012)。 - Lundin

7
不,这并不有用。 malloc 的整个目的是让多个进程动态共享系统中所有可用的RAM内存,当它们需要时。这又意味着您拥有一个多进程系统,并且可用RAM的数量是巨大的,但也是可变或未知的。
在较小的嵌入式系统中,这种内存共享没有任何意义,这些系统可以是“裸机”(没有操作系统)或使用RTOS。与PC不同,这样的嵌入式系统完全确定,因此您始终知道最坏情况下所需的RAM量。您还知道芯片上有多少RAM。
在这些系统上使用malloc的需求通常源于困惑的PC程序员,他们在学习之前已经开始进行嵌入式编程。
详见此处

2
我认为malloc在单线程应用程序中非常有用,特别是当程序需要创建大小不同的内存对象时。例如保存字符串。如果您可以从空闲内存池中分配可变大小的块,则可以创建比所有固定大小的对象更多的对象。但这会让您担心碎片化、垃圾回收和内存泄漏等问题。 - infixed
3
在确定性嵌入式系统中,不存在具有可变大小的“内存对象”的情况。必须始终存在一个上限。您必须为最坏情况进行设计,必须拥有足够的内存来处理最坏情况,就这样。请参阅我链接的帖子。 - Lundin
4
总结:如果你真正知道你在做什么,那么你得到的程序将比盲目调用 malloc 要高效得多,而不知道它实际上是做什么的。后者是 PC 程序员的心态,在设计嵌入式系统时只会带来悲哀和痛苦。你必须完全掌握程序使用多少内存的控制权,没有其他的。交付可能突然耗尽内存的固件并不是专业工程,那只是江湖骗术。 - Lundin
2
@lundin。你知道存储速度层次和权衡的概念并不新鲜。没有人会盲目地调用malloc。随着嵌入式系统变得更加强大,它们正在进入常规系统不久前操作的领域。也许你想要一个确定性系统,例如每次从SD卡上通过SPI获取相同数据而不是将其缓存在RAM中。但我不想这样做。是的,我们必须处理最坏情况。但这并不意味着你必须一直生活在其中。 - infixed
3
malloc并不是全部、唯一或甚至是主要用途。你不能过于强调它的有用性或无用性。有用性和适宜性不是同一回事。 - Clifford
显示剩余3条评论

0

在这样的系统中使用malloc是没有任何意义的。当您进行系统工程时,包括资源分配在内。作为单个任务,该任务拥有系统中的所有资源。因此,在设计时确定需要多少每种资源,包括内存。在运行时很久之前,您已经知道哪些结构体需要多少内存,因此没有理由为已知答案的事情添加额外的代码风险。如果您已经做了5年,那么您已经知道这一点。如果您没有进行系统工程,则应开始看到过去的工作在现场失败。


2
任务数量与动态内存分配的实用性并没有太大关系,而是与数据和条件的可变性有关。动态内存(重新)分配确实存在危险,但仅因为只有一个任务拥有所有内存并不改变设计如何使用它的需求 - 没有任何规定必须要有操作系统才能使用malloc()。静态分配确实更安全 - 但在可能的情况下使用动态内存响应可变条件也是明智的方法。 - Chris Stratton

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接