c - C 标准对使用的堆栈空间量有任何保证吗?
问题描述
我正在做嵌入式编程,其中节省内存很重要。
下面的 C 代码在运行时会占用多少堆栈空间?
if (send_small_message) {
uint8_t buffer[16000];
// do something with the buffer
} else {
uint8_t buffer[32000];
// do something the with buffer
}
某些编译器可以决定为两个缓冲区分配 16000 + 32000 = 48kB 堆栈空间吗?或者是否保证由于两个缓冲区永远不会同时使用,编译器将只分配 32kB - 较大缓冲区的大小?
跟进问题:
void SendSmallMessage() {
uint8_t buffer[16000];
// do something with the buffer
}
void SendLargeMessage() {
uint8_t buffer[32000];
// do something with the buffer
}
某些编译器编译的代码是否可以在运行时使用 16000 + 32000 字节来执行以下代码段:
if (send_small_message) {
SendSmallMessage();
} else {
SendLargeMessage();
}
解决方案
C标准是否保证使用的堆栈数量?
对此没有任何保证。C 标准没有提到堆栈之类的概念。您甚至可以为完全没有堆栈的低级 CPU 编写 C。
然而,C 标准确实保证uint8_t
1 字节大,并且 1 字节在您的系统上是 8 位(否则uint8_t
将不可用)。
下面的 C 代码在运行时会占用多少堆栈空间?
某些编译器可以决定为两个缓冲区分配 16000 + 32000 = 48kB 堆栈空间吗?
特定于系统,但也取决于函数的编写方式以及发生的优化。不过,一般来说,现实世界的系统会根据所有可能的执行路径为函数所需的堆栈分配空间。所以很可能许多编译器会分配 16k + 32k。
但是谁在乎呢,因为在任何已知系统中在堆栈上分配大量内存是没有意义的。不在高端、类似 PC 的系统上,当然也不在内存受限的嵌入式系统上。你会得到到处都是堆栈溢出。
嵌入式中的一般经验法则是永远不要在堆栈上分配任何形式的缓冲区,但始终具有静态存储持续时间。在类似 PC 的系统上,堆分配是另一种选择。
推荐阅读
- for-loop - 榆树 - 树 - 将分支添加到另一棵树 - 递归 forloop
- regex - 用于编号反向引用和其他替换模式占位符的 VSCode 正则表达式表示法
- python - 递归替换excel文件目录中的字符串
- c++ - 有没有办法从函数返回新对象或对现有对象的引用?
- php - 未定义变量:Blade Laravel 6.4.0 中的类别
- c# - 验证后切换复选框值
- c# - 无法读取 excel XLSM 文件以绑定到 datagridview
- c# - 试图在 C# 中结合 Luis 和附件
- docker - Split health checks cannot set custom path
- c++ - 将整数范围映射到另一个范围