我目前正在調整一些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