我目前正在调整一些Arduino示例代码以适合我的需求。下面的代码片段让我困惑:我怎样才能避免把这个变量放在栈上?
// Dont put this on the stack:
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
是什么意思把buf
变量在堆栈上?我怎样才能避免这样做?如果我做到了,会发生什么坏事?
我目前正在调整一些Arduino示例代码以适合我的需求。下面的代码片段让我困惑:我怎样才能避免把这个变量放在栈上?
// Dont put this on the stack:
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
是什么意思把buf
变量在堆栈上?我怎样才能避免这样做?如果我做到了,会发生什么坏事?
程序堆栈的大小有限(即使在桌面计算机上,它通常以兆字节为上限,而在Arduino上可能会小得多)。
函数的所有函数局部变量都以LIFO方式存储在那里; main
方法的变量位于堆栈的底部,在main
之上调用的函数的变量等等; (通常)在输入函数时保留空间,在函数返回之前不会回收空间。如果一个函数分配一个真正巨大的缓冲区(或者调用链中的多个函数分配稍小的缓冲区),则可以快速接近堆栈限制,这会导致程序崩溃。
这听起来像你的数组正在被分配外部一个函数,把它放在全局范围。这样做的缺点是只有一个共享缓冲区(所以两个函数不能在没有协调访问的情况下同时使用它,而为每个函数独立保留一个堆栈缓冲区),但好处是它不会花费堆栈用它;它是从程序存储器的一个单独部分(通常是无界的部分,或者至少有千兆字节的限制,而不是兆字节范围)分配的。
因此,要回答你的问题:
是什么意思把
buf
变量在堆栈上?
这将是在栈上,如果它:
static
(或thread_local
,尽管这比你更复杂现在应该关心);如果它的声明static
的功能范围,它基本上是只能在特定的功能我怎样才能避免这样直接引用全局内存?
不要在函数范围声明巨大的非static
数组。
如果我这样做会发生什么坏事?
如果数组足够大,可能会遇到堆栈溢出耗尽可用堆栈空间,导致程序崩溃。
我认为这意味着数组应该有静态存储时间而不是自动存储时间。您可以在名称空间中声明它,也可以根据上下文将其声明为带有静态指定符的本地数组。 –
根据'RH_RF95_MAX_MESSAGE_LEN'的大小和可用堆栈的大小,您可以发现自己有一个...等待它... Stack Overflow。 – user4581301