2017-09-26 96 views
0

我目前正在调整一些Arduino示例代码以适合我的需求。下面的代码片段让我困惑:我怎样才能避免把这个变量放在栈上?

// Dont put this on the stack: 
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN]; 

是什么意思把buf变量在堆栈上?我怎样才能避免这样做?如果我做到了,会发生什么坏事?

+1

我认为这意味着数组应该有静态存储时间而不是自动存储时间。您可以在名称空间中声明它,也可以根据上下文将其声明为带有静态指定符的本地数组。 –

+1

根据'RH_RF95_MAX_MESSAGE_LEN'的大小和可用堆栈的大小,您可以发现自己有一个...等待它... Stack Overflow。 – user4581301

回答

4

程序堆栈的大小有限(即使在桌面计算机上,它通常以兆字节为上限,而在Arduino上可能会小得多)。

函数的所有函数局部变量都以LIFO方式存储在那里; main方法的变量位于堆栈的底部,在main之上调用的函数的变量等等; (通常)在输入函数时保留空间,在函数返回之前不会回收空间。如果一个函数分配一个真正巨大的缓冲区(或者调用链中的多个函数分配稍小的缓冲区),则可以快速接近堆栈限制,这会导致程序崩溃。

这听起来像你的数组正在被分配外部一个函数,把它放在全局范围。这样做的缺点是只有一个共享缓冲区(所以两个函数不能在没有协调访问的情况下同时使用它,而为每个函数独立保留一个堆栈缓冲区),但好处是它不会花费堆栈用它;它是从程序存储器的一个单独部分(通常是无界的部分,或者至少有千兆字节的限制,而不是兆字节范围)分配的。

因此,要回答你的问题:

是什么意思把buf变量在堆栈上?

这将是在栈上,如果它:

  1. 在功能范围,而不是全局范围内声明的,
  2. 未声明为static(或thread_local,尽管这比你更复杂现在应该关心);如果它的声明static的功能范围,它基本上是只能在特定的功能

我怎样才能避免这样直接引用全局内存?

不要在函数范围声明巨大的非static数组。

如果我这样做会发生什么坏事?

如果数组足够大,可能会遇到堆栈溢出耗尽可用堆栈空间,导致程序崩溃。

相关问题