2017-09-26 25 views
0

私は現在、私のニーズに合ったアルドゥイノのコード例を採用しています。次のスニペットは、私を混乱させる:この変数をスタックに置かないようにするにはどうすればよいですか?

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

それがスタックにbuf変数を置くために何を意味するのでしょうか?これを避けるにはどうすればいいですか?もし私がそれをしたら、どんな悪いことが起こるのだろうか?

+1

私は、このコメントは、自動保存期間ではなく静的な保存期間を持つことを意味すると考えています。名前空間で宣言するか、コンテキストに応じて静的指定子を持つローカル配列として宣言することができます。 –

+1

'RH_RF95_MAX_MESSAGE_LEN'のサイズと利用可能なスタックのサイズに応じて、あなたはそれを待つことができます...スタックオーバーフロー。 – user4581301

答えて

4

プログラムスタックのサイズは限られています(デスクトップコンピュータでも、通常はメガバイト単位で制限されていますが、Arduinoではそれよりもはるかに小さいことがあります)。

関数のすべての関数ローカル変数は、そこにLIFO形式で格納されます。 mainメソッドの変数はスタックの一番下にあり、その上にmainという関数の変数などがあります。スペースは(通常)関数の入力時に予約され、関数が戻るまでは再利用されません。関数が本当に巨大なバッファを(または呼び出しチェーンの複数の関数を少し小さいバッファを割り当てる)割り当てる場合は、スタック制限に急速に近づくことができ、プログラムがクラッシュする可能性があります。

配列がの外部に割り当てられているようですが、の関数がグローバルスコープに配置されています。欠点は、共有バッファが1つしかないことです(したがって、2つの関数はアクセスを調整せずに同時に使用することはできませんが、スタックバッファは関数ごとに独立して予約されます)。しかし、これを使って;それはプログラムメモリの別のセクション(通常は無制限のセクション、または少なくともメガバイトの範囲ではなくギガバイトの制限があるセクション)から割り当てられます。

だからあなたの質問にお答えします

それがスタックにbuf変数を置くために何を意味するのでしょうか?

  1. は、関数のスコープではなく、グローバルスコープで宣言され、それはあなたよりも複雑だけれども
  2. は、static(またはthread_localとして宣言されていない:それは場合

それはスタックになります今気にする必要があります)。それは、関数スコープでstatic宣言だ場合、それは基本的にその特定の機能に直接参照できるグローバルメモリ

は、どのように私はこれを行うことを避けることができますか?

大規模な非static配列を関数スコープで宣言しないでください。

私がそれをした場合、どんな悪いことが起こる可能性がありますか?

アレイのサイズが十分大きい場合、使用可能なスタック領域が不足してスタックオーバーフローが発生し、プログラムがクラッシュする可能性があります。

関連する問題