私は現在、私のニーズに合ったアルドゥイノのコード例を採用しています。次のスニペットは、私を混乱させる:この変数をスタックに置かないようにするにはどうすればよいですか?
// Dont put this on the stack:
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
それがスタックにbuf
変数を置くために何を意味するのでしょうか?これを避けるにはどうすればいいですか?もし私がそれをしたら、どんな悪いことが起こるのだろうか?
私は現在、私のニーズに合ったアルドゥイノのコード例を採用しています。次のスニペットは、私を混乱させる:この変数をスタックに置かないようにするにはどうすればよいですか?
// Dont put this on the stack:
uint8_t buf[RH_RF95_MAX_MESSAGE_LEN];
それがスタックにbuf
変数を置くために何を意味するのでしょうか?これを避けるにはどうすればいいですか?もし私がそれをしたら、どんな悪いことが起こるのだろうか?
プログラムスタックのサイズは限られています(デスクトップコンピュータでも、通常はメガバイト単位で制限されていますが、Arduinoではそれよりもはるかに小さいことがあります)。
関数のすべての関数ローカル変数は、そこにLIFO形式で格納されます。 main
メソッドの変数はスタックの一番下にあり、その上にmain
という関数の変数などがあります。スペースは(通常)関数の入力時に予約され、関数が戻るまでは再利用されません。関数が本当に巨大なバッファを(または呼び出しチェーンの複数の関数を少し小さいバッファを割り当てる)割り当てる場合は、スタック制限に急速に近づくことができ、プログラムがクラッシュする可能性があります。
配列がの外部に割り当てられているようですが、の関数がグローバルスコープに配置されています。欠点は、共有バッファが1つしかないことです(したがって、2つの関数はアクセスを調整せずに同時に使用することはできませんが、スタックバッファは関数ごとに独立して予約されます)。しかし、これを使って;それはプログラムメモリの別のセクション(通常は無制限のセクション、または少なくともメガバイトの範囲ではなくギガバイトの制限があるセクション)から割り当てられます。
だからあなたの質問にお答えします
それがスタックに
buf
変数を置くために何を意味するのでしょうか?
- は、関数のスコープではなく、グローバルスコープで宣言され、それはあなたよりも複雑だけれども
- は、
static
(またはthread_local
として宣言されていない:それは場合
それはスタックになります今気にする必要があります)。それは、関数スコープでstatic
宣言だ場合、それは基本的にその特定の機能に直接参照できるグローバルメモリ
は、どのように私はこれを行うことを避けることができますか?
大規模な非static
配列を関数スコープで宣言しないでください。
私がそれをした場合、どんな悪いことが起こる可能性がありますか?
アレイのサイズが十分大きい場合、使用可能なスタック領域が不足してスタックオーバーフローが発生し、プログラムがクラッシュする可能性があります。
私は、このコメントは、自動保存期間ではなく静的な保存期間を持つことを意味すると考えています。名前空間で宣言するか、コンテキストに応じて静的指定子を持つローカル配列として宣言することができます。 –
'RH_RF95_MAX_MESSAGE_LEN'のサイズと利用可能なスタックのサイズに応じて、あなたはそれを待つことができます...スタックオーバーフロー。 – user4581301