2017-09-26 172 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數組。

如果我這樣做會發生什麼壞事?

如果數組足夠大,可能會遇到堆棧溢出耗盡可用堆棧空間,導致程序崩潰。

相關問題