静的局所変数は、関数内でキーワード static を使用して定義されます。通常の局所変数とは異なり、関数の呼び出し間でその値を保持し、一度だけ初期化されます。この変数はプログラムの全ライフサイクルの間存在し、関数内でのみ可視です。
通常の局所変数:
void func() { int count = 0; // 毎回初期化される count++; printf("%d\n", count); }
毎回出力は 1 です。
静的局所変数:
void func() { static int count = 0; // 一度だけ初期化される count++; printf("%d\n", count); }
連続して呼び出すと、出力は 1, 2, 3, ... となります。
使用法: 関数の呼び出し回数をカウントしたり、単純な値をキャッシュするのに便利です。
「静的局所変数は関数の終了後に破棄されますか、次回関数を呼び出したときにその値はどうなりますか?」
よく「破棄される」と答える人がいますが、それは間違いです。
正しい答え: 静的局所変数はプログラムの全ライフサイクルの間存在します。関数の呼び出し間でその値を保持し、関数に最初に入るとき、または main の前に一度だけ初期化されます。
物語 1
あるプロジェクトで、関数を通じてモジュールへの入力時間を測定していました。 int counter = 0; を static int counter = 0; と間違えたため、関数は常に 1 を返し、統計は無意味になりました。
物語 2
スレッドセーフでないサービスで、異なるスレッドから呼び出される関数に静的変数を使用しました。これにより競合状態や偶発的な不正な結果が発生しました。共有メモリが保護されていないことを考慮しませんでした。
物語 3
動的に割り当てたメモリへのポインタを静的変数に保持してキャッシュしました。関数を再起動する際に古いメモリを解放せず、毎回メモリリークが発生しました。