C言語では、実際には変数が格納される場所は定義されていません。ただし、静的、自動、動的の3つのストレージクラスを定義します。
静的変数は、プログラムの初期化(の前main()
)中に作成され、プログラムが終了するまで存在し続けます。ファイルスコープ(「グローバル」)および静的変数は、このカテゴリに分類されます。これらは通常、データセグメントに格納されますが、C標準ではこれが当てはまる必要はなく、場合によっては(Cインタープリターなど)、ヒープなどの他の場所に格納されることもあります。
自動変数は、関数本体で宣言されたローカル変数です。これらは、プログラムフローが宣言に達するときまたはその前に作成され、スコープ外になると破棄されます。これらの変数の新しいインスタンスは、再帰関数呼び出し用に作成されます。スタックはこれらの変数を実装するための便利な方法ですが、繰り返しになりますが、必須ではありません。必要に応じて、ヒープに自動を実装することもできます。自動は通常、レジスタにも配置されます。多くの場合、自動変数はその存続期間中にスタックとヒープの間を移動します。
register
自動変数の注釈はヒントであることに注意してください。コンパイラーはそれを使って何もする義務はなく、実際、多くの最新のコンパイラーはそれを完全に無視します。
最後に、動的オブジェクト(Cには動的変数などはありません)はmalloc
、calloc
または他の同様の割り当て関数を使用して明示的に作成された値を参照します。それらは明示的に作成されたときに存在し、明示的に解放されたときに破棄されます。ヒープは、これらを配置するのに便利な場所です。つまり、このスタイルの割り当てを実行する機能に基づいてヒープを定義します。しかし、繰り返しになりますが、コンパイラの実装は自由にやりたいことができます。コンパイラーが静的分析を実行して動的オブジェクトの存続期間を判別できる場合、それをデータ・セグメントまたはスタックに移動できる可能性があります(ただし、この種の「エスケープ分析」を実行するCコンパイラーはほとんどありません)。
ここで重要なポイントは、C言語標準では、特定の値が存在する期間のみが定義されていることです。そして、その時点でのこのライフタイムの最小範囲-必要以上に長く残る可能性があります。これをメモリに正確に配置する方法は、言語とライブラリの実装に大きな自由が与えられる主題です。