我收到了一块基于8051的板子,上面运行着自制的嵌入式操作系统。我正在使用SDCC在OS之上创建应用程序。但是malloc不可用,所以我必须静态分配内存。为什么呢?难道malloc不应该是编译器中动态链接库的一部分吗?
TL;DR:
为什么和何时C语言中的malloc()函数不可用?
总体而言,每个符合标准的、托管的C实现都会提供malloc()
函数,但还有其他类型,包括另一种符合标准的类型。
malloc()不应该是编译器内的动态库吗?
不完全正确。 malloc()
是C标准库的一部分,因此每个符合标准的、托管的C实现都会提供它。一个C实现包括将C源代码转换为可执行程序的系统以及运行结果程序的机制和环境。前者通常围绕编译器展开。后者包括实现提供的C标准库的所有特性,如果malloc
可用,则在这部分中存在。因此,严格来说,malloc()
并不是编译器的组成部分。
我确信这不是你想引入的区别,但它确实与答案有关。请注意,我说malloc()
由托管实现提供。这些是您在通用操作系统上通常遇到的类型。它们创建通过主机OS以标准方式启动的程序,并与OS一起提供C标准库的所有特性。但也有独立实现。其中一个关键区别是,独立实现不需要提供大多数标准库,包括malloc()
。
您通常会发现,在嵌入式系统中使用独立实现,例如您的系统。它们还用于操作系统内核、引导加载程序和其他直接在裸机上运行的程序。您的程序在操作系统之上运行使得您的环境在嵌入式系统中有点像Cadillac,但这并不能保证C实现是托管实现。只要它不提供malloc()
,它就不能成为符合标准的托管实现,但它可以成为符合标准的独立实现。它应该记录其声称的任何一个。如果它是独立的,但提供了其他标准库函数,那么您可以将其视为奢侈品。
malloc()
将在执行环境中对程序可用。 没有任何库函数需要C标准提供独立实现,甚至没有malloc()
,标准对不符合要求的实现没有任何要求。 没有替代方法,只能阅读您的实现文档,至少足以检查它是否声称为符合标准的托管实现。 - John Bollinger遵循此规则的一种方法是:不要在系统中引入或实现20.4 - 不得使用动态堆内存分配。
malloc()
和其他动态内存分配函数。通过在项目中包含C库,您可以利用malloc、printf等函数。请注意,8051是一个低内存占用设备,仅有几KB的内存。因此,包含C库会增加输出.hex文件的大小,并且可能会导致内存不足。
malloc
是标准库的一部分,不是编译器的一部分。因此,您的板子必须提供实现malloc
的库。 - Paul Ogilvie