【问题标题】:Dynamic memory allocation in embedded C嵌入式 C 中的动态内存分配
【发布时间】:2016-01-30 13:53:18
【问题描述】:

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

Typedef struct {
  Char varA;
  Char varB 
} myStruct ;

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

  return ;    
}

【问题讨论】:

  • 不要大写TypedefCharVoid
  • 你使用的标准库有这些功能吗?那么是的,您可以使用这些功能。现在应该你使用这些功能吗?这取决于您的目标平台、您的要求、您的(软件)设计以及许多其他因素。这里没有明确的“是”或“否”答案。
  • 对了,你不是说mallocfree吗?
  • 最后,总是 freemalloc (直接或间接)。特别是在您不确定操作系统(如果有)是否会为您释放内存的系统上。
  • 这取决于你所说的“嵌入式系统”。

标签: c memory embedded malloc ram


【解决方案1】:

对于阻止使用动态内存的嵌入式系统,没有什么特别的。

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

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

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

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

【讨论】:

  • 还要考虑内存碎片。
  • @Technophile :最终,碎片是非确定性时序分配失败的原因。我选择不单独突出显示它;我列出的是动态分配的问题,而不是这些问题的原因。
【解决方案2】:

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

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

【讨论】:

    【解决方案3】:

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

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

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

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

    【讨论】:

    • 在 Internet 上的其他地方被“解释”并不成立。您引用的示例是具有 4kb RAM 的系统。并非所有嵌入式系统都具有这种性质。在一些嵌入式系统中不使用动态内存分配的原因有很多,但您必须了解这些原因,以及特定系统的限制和要求才能做出明智的决定,而不是遵循一些不了解的情况教条。此外,我建议“许多嵌入式系统编程标准”而不是“几乎所有”——即使它是真实的,也很难有证据支持
    猜你喜欢
    • 2011-09-06
    • 1970-01-01
    • 2018-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-07
    • 2015-06-27
    相关资源
    最近更新 更多