C/C++における関数レベルの静的変数はいつ初期化されるのか?
静的変数(static変数)は、staticキーワードを使用して定義できます。静的変数はプログラムの実行中ずっとメモリ上に存在し続け、その寿命はプログラム全体の実行期間に及びます。これは、関数が実行されている間だけメモリに存在し、関数の終了とともに破棄される自動変数(ローカル変数)とは大きく異なる点です。
初期化のタイミング
関数レベルの静的変数の場合、メモリ領域自体はプログラムのロード時に確保されますが、実際に作成され、初期化が行われるのは最初にその変数が使用されたときです。つまり、関数が何度呼び出されても、初期化処理が実行されるのは一度きりであり、以降の呼び出しでは前回の値がそのまま引き継がれます。
サンプルプログラム
以下は、C言語で関数レベルの静的変数の動作を示すサンプルプログラムです。
#include<stdio.h>
int func() {
static int num = 0;
num += 5;
return num;
}
int main() {
for(int i = 0; i<5; i++) {
printf("%d\n", func());
}
return 0;
}出力結果
上記プログラムの実行結果は以下の通りです。
5 10 15 20 25
プログラムの解説
まず、関数func()には、0で初期化された静的変数numが定義されています。関数が呼び出されるたびにnumに5が加算され、その値が返されます。該当するコード部分は以下の通りです。
int func() {
static int num = 0;
num += 5;
return num;
}次に、main()関数では、forループを使ってfunc()を5回呼び出し、戻り値であるnumの値を出力しています。numは静的変数であるため、プログラムの実行中はメモリ上に値が保持され続け、呼び出しごとに5、10、15、20、25というように一貫して増加していくのです。該当するコード部分は以下の通りです。
int main() {
for(int i = 0; i<5; i++) {
printf("%d\n", func());
}
return 0;
}補足:C++11以降のスレッドセーフな初期化
C++では、C++11規格以降、関数内ローカルの静的変数の初期化はスレッドセーフであることが保証されています。複数のスレッドが同時に同じ静的変数へ初めてアクセスしても、初期化は必ず一度だけ実行され、他のスレッドは初期化の完了を待機します。この仕組みは、シングルトンパターンの実装などでよく活用されています。
-
C/C++のmemcpy()関数の使い方と実例解説
この記事では、C++ STLにおけるmemcpy()関数の動作、構文、および具体的な使用例について詳しく解説します。 memcpy()とは? memcpy()関数は、C++ STLに組み込まれた標準関数の一つで、<cstring>ヘッダーファイルで定義されています。この関数はメモリブロックをコピーするために使用され、あるメモリ位置から別のメモリ位置へ、指定されたバイト数分のデータを転送します。 関数の実行結果は、データのバイナリコピーとなります。重要な点として、memcpy()は終端のNULL文字やその他の終端記号をチェックしません。単純にソースから指定されたバイト数(num)をそ
-
C/C++で学ぶAA木(AA Tree)とは?基本概念と平衡化操作を徹底解説
AA木(AA Tree)とはコンピュータサイエンスにおいて、AA木(AA Tree)とは、順序付きデータを効率的に格納・検索するために実装された平衡木(バランスドツリー)の一種です。AA木は、赤黒木(Red-Black Tree)の変種として扱われます。赤黒木は二分探索木の一形態であり、要素の追加や削除を効率的にサポートします。赤黒木と大きく異なる点は、AA木では赤いノードを右の子としてのみ追加でき、左の子としては配置できないという制約があることです。この制約により、2-3-4木ではなく2-3木をシミュレートすることになり、その結果、木の保守操作が大幅に簡素化されます。赤黒木の平衡化アルゴリズ