如何避免将此变量放在堆栈上?

时间:2017-09-26 23:51:00

标签: c++ arduino stack global-variables

我目前正在调整一些Arduino代码示例以满足我的需求。以下代码段让我感到困惑:

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

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

1 个答案:

答案 0 :(得分:4)

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

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

听起来您的数组正在在函数外部分配,将其置于全局范围内。这样做的缺点是只有一个共享缓冲区(因此两个函数不能同时使用它而不协调访问,而堆栈缓冲区将为每个函数独立保留),但好处是它没有“#”。成本堆栈使用它;它是从程序存储器的一个单独部分分配的(一个部分通常是无限制的,或者至少有千兆字节的限制,而不是兆字节范围)。

所以回答你的问题:

  

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

如果它会在堆栈上:

  1. 在函数范围而不是全局范围内声明,
  2. 未被声明为static(或thread_local,虽然这比你现在应该关心的更复杂);如果它在功能范围内声明static,它基本上是全局内存,只能在该特定功能中直接引用
  3.   

    我怎样才能避免这样做?

    不要在功能范围内声明巨大的非static数组。

      

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

    如果数组足够大,你可能会因为可用的堆栈空间不足而导致堆栈溢出,从而导致程序崩溃。