提问人:Ian Stewart 提问时间:10/7/2023 最后编辑:Ian Stewart 更新时间:10/9/2023 访问量:201
MISRA C 建议不要使用 malloc,这是否意味着 calloc 更安全?
MISRA C advises against malloc, does this mean calloc is far more secure?
问:
我使用 C 已经有几年了,但直到最近才认真努力理解未定义的行为和 C 内存泄漏等陷阱。这是因为现在我在某些代码中多次使用 calloc。MISRA C 的建议是:避免使用容易失败的函数和构造,例如,malloc 可能会失败。我认为这意味着内存分配可能是一个问题,这是否意味着 calloc 是安全的? 如果不是,这是否可取:
uint32_t *array;
array = calloc(length, 32);
还是只是装点门面?
谢谢你的任何建议,我真的很想避免不良做法。
答:
任何调用都可能失败。如果没有要分配的内存,malloc 将返回 null。如果不检查此返回值,并为内存不足事件提供适当的处理逻辑,则程序可能会崩溃。通常,您唯一能做的就是向用户提供有关情况的消息。
如果您处于安全关键环境中,软件崩溃可能导致车祸,这是非常糟糕的,因此对于任何涉及汽车实时操作的循环,最好避免动态内存分配,因为潜在的递归。
以 calloc 形式装点门面不会有任何区别。
评论
只是装点门面吗?
确实如此。是否使用 or(与 + 初始化相同)并不重要。malloc
calloc
malloc
关键是检查返回值。
MISRA:
避免使用容易失败的函数和构造
脱离上下文,这让想要进行动态内存分配的人别无选择,只能
- 忽略 MISRA 的建议,只需确保检查每个分配。
- 在程序启动时进行较大的静态分配,并将其用作整个程序中唯一的内存池。提供证据,证明您的计划永远不会超过所做的分配。
评论
MISRA C 在谴责 malloc + 朋友时出奇地简短。动态分配是各种安全相关应用中的主要罪过,其他所有相关的标准也都禁止它(IEC61508 + 和其他“SIL”标准(火车、家用电器等)、ISO 26262、DO178、JSF 和 NASA 标准等)。
由内存不足导致的潜在错误可能是该函数问题最少的问题 - 因为如果你的内存不足,这意味着你的整个程序设计被破坏了,这不是 malloc 本身的错。malloc
这篇 Codidact 博文详细回答了您的问题,包括嵌入式系统中 malloc 和动态分配的众多严重问题:
为什么我不应该在嵌入式系统中使用动态内存分配?
至于可以使用什么来代替,与安全相关的应用程序使用静态大小的缓冲区。在某些情况下,内存池也是可以接受的,只要您在那里进行错误检查/处理,请在此处查看我的答案。
评论
MISRA C 的建议是:避免使用容易失败的函数和构造,例如,malloc 可能会失败。我认为这意味着内存分配可能是一个问题,这是否意味着 calloc 是安全的?
MISRA C:2012(并持续到 :2023)非常清楚:
- 指令 D.4.12 - 不得使用动态内存分配
如果这还不够:
- 规则21.3 - 不得使用内存分配和解除分配功能
<stdlib.h>
在规则 21.3 中,放大甚至列出了以下功能:
calloc
和malloc
realloc
aligned_alloc
free
因此,对您的问题的简单回答是:不,如果您希望符合 MISRA C 标准,calloc
是不行的。
评论
<stdint.h>
<stdlib.h>
<stdlib.h>
评论
malloc
calloc
malloc
malloc
calloc
malloc
calloc
calloc
malloc