嵌入式C中的动态内存分配

时间:2015-10-30 07:39:32

标签: c memory embedded malloc ram

我可以在嵌入式C中使用malloc和delete函数吗?例如,我有一个函数,其中在函数malloc的结构上创建了指针。这个函数在ram中返回地址,我可以使用它。退出我的功能,在那里分配了内存,这个指针将被删除或者这个内存为此保留,而不是将函数删除终止?

Typedef struct {
  Char varA;
  Char varB 
} myStruct ;

Void myfunc ( void) 
{
  myStruct * ptrStruct = ( myStruct *) malloc ( sizeof (myStruct)) ;
  // Code here 
  //........

  return ;    
}

3 个答案:

答案 0 :(得分:11)

通常,您不应该在嵌入式系统中使用malloc,因为这样做没有任何意义 as explained here。特别是,在裸机系统上使用它并没有任何意义。

使用动态内存分配的地方是大型托管,多进程系统,其中多个进程共享相同的RAM。如果您对嵌入式系统的定义是Android智能手机或便携式PC,那么可以使用malloc。

如果你发现自己在其他地方使用它,那几乎可以肯定意味着你的程序设计存在根本缺陷,而且你也不知道堆是如何工作的。

此外,几乎所有嵌入式系统编程标准都禁止动态内存分配。

答案 1 :(得分:5)

没有任何特定的嵌入式系统可以阻止动态内存的使用。

但是,您可能需要以多种方式为其提供支持,例如:

  • 您需要确保链接器为动态堆分配足够的空间。在堆栈和任何其他保留分配之后,某些链接描述文件可能已经自动将所有剩余内存分配给堆。
  • 您可能需要实现低级存根以允许库访问堆内存 - 例如,在newlib库中,您需要为sbrk_r()等实现malloc()才能正常工作。
  • 在多线程系统中,您可能需要实现互斥存根以确保安全堆分配。如果库没有提供这样的存根,那么malloc() / free()等在这样的环境中使用是不安全的,你应该编写外部声明锁的包装函数。

然而,为什么您可能会选择避免在嵌入式系统中使用动态内存(或至少是标准库实现的动态内存),这有很多原因:

  • 标准分配方案具有不适合硬实时系统的非确定性时序。
  • 您需要为每个分配优雅地处理分配失败的可能性。安全地处理潜在的非确定性运行时错误比仅仅让编译器告诉您在构建时没有足够的内存更复杂。
  • 你需要防止内存泄漏;对于任何系统都是如此,但没有操作系统可以管理内存耗尽并杀死泄漏过程,您的系统将如何运作?
  • 如果没有互斥锁存根或包装函数,标准库堆管理可能不是线程安全的。
  • 破坏堆的错误不太可能立即影响执行,通常只会在执行新堆操作时导致可观察到的失败,从而导致与实际原因无关的时间和位置的非确定性行为 - 使它们变得非常困难诊断。任何系统都是如此,但是交叉托管的嵌入式系统中的调试工具通常不如自托管系统那么复杂。

答案 2 :(得分:2)

是的,您可以在嵌入式C中使用malloc。某些嵌入式系统具有自己的封装内存分配API。 malloc()是C lib API。

内存是从堆分配的,堆是由系统设计者定义的专用内存范围。如果在函数退出后没有释放已分配的内存,则分配的内存将被保留,其他进程无法使用它。通常,它是内存泄漏。如果释放已分配的内存但在此之后仍然使用指针,则它是一个狂野指针并将导致未知行为。