1

プロセッサで利用可能なメモリの限界を押し上げているかなり大きなArduinoスケッチがあります。私はメモリを解放し、グローバル変数の使用を可能な限り減らしています。使用可能なメモリを確認するために使用していMemoryFree.hます(詳細はここにあります)。作業中のスケッチがありますが(ここに投稿するには長すぎます)、いくつかの変数(使用可能なメモリの範囲内)を使用して別の関数を追加すると、メモリがないためにシステムがクラッシュまたは停止します。

次の関数を追加しました。

boolean moved(){

int yreadings[4];
int zreadings[4];


free(&yreadings);
free(&zreadings);
}

次に、メインループに次のコードを追加しました。

 Serial.print("Mem is ");
 Serial.println(freeMemory());
 moved();

ループ内で以下の関数全体がコメント化されている場合moved()、次の出力が得られます。

Mem is 499

各反復で、反復ごとにメモリが失われないことを示します。

しかし、関数とその呼び出しのコメントを外すと、次の出力が得られます。

Mem is 499
Mem is -16094

クラッシュする前の1行目と2行目...

メモリが永続的であっても、これは反復ごとに499バイト全体よりもはるかに少ない量を使用するべきではありませんか?それでも、どのようにしてメモリを失うのですか?

更新:さらに奇妙なことに、moved()関数を削除して整数配列をグローバルに宣言すると、まだ499のメモリ読み取り値が得られます。どうですか?24個の整数が消費するメモリの量だけ減らすべきではありませんか?

4

1 に答える 1

3

関数の実行の一部にのみ自動ストレージが存在する必要がある場合は、それらをスコープブロック内に配置できます。

void foo(void) {

   // some code where neither reading variable is occupying memory

   {
      int yreadings[4];
      int zreadings[4];

      // here these variable are taking up memory

   }

   // other code where neither reading variable is occupying memory
}

もちろん、それらはそのブロックでのみ使用できます。


私のコメントを拡張するために、異なる期間を持つ3つのクラスのメモリ使用があります

  • static関数、メソッド、またはクラスのコンテキストで宣言されたグローバル変数と変数は、プログラムの存続期間全体にわたって存在します
  • 自動変数(関数またはメソッド内で宣言されたもの)は、そのスコープから呼び出された他のサブプログラムの存続期間を含む、スコープの存続期間中存在します
  • new動的割り当ては、 1またはalloc関数ファミリ(簿記上の理由で要求するサイズよりも常に少し大きくなります)から取得したメモリのブロックであり、割り当てたときからdeleteまたはfree(それぞれ)を呼び出すまで持続します。

1これをオーバーライドnewすると、適用される場合とされない場合がありますが、オーバーライドする場合は、自分自身に何をしたかを理解することが重要です。

于 2012-12-01T21:13:08.383 に答える