- ベストアンサー
C言語におけるローカル変数が使用するメモリについて
例のようなC言語のプログラムを動かした場合、 確保されるメモリ領域はどうなるのでしょうか。 例 #include <stdio.h> int main(void) { int a = 0; } このとき、変数aはint型なのでスタック領域に4バイトのメモリが確保されると理解しています。 と同時にaという変数名と確保されたスタック領域の番地を紐づけるようなメモリがどこかに確保されるのではないかと思ってるのですが、この理解で正しいでしょうか。 またその場合は変数aの番地はどの領域に確保されるのでしょうか。 ご教示お願いいたします。
- みんなの回答 (5)
- 専門家の回答
質問者が選んだベストアンサー
安直な表現をしましょうか・・・。変数aが****番地にあるという事実に興味があるのは、人間とコンパイラ・リンカだけです。全てのプログラムは、最終的には、機械語というCPU固有の命令体系に変換されるのですが、この領域では、CPUは、あくまでメモリーアドレスの絶対値だけにしか興味がないのです。 逆の表現をすると、メモリーアドレス****と書いても「人間にとって」わかりにくいので、これを変数aと「人間が書くことにした」だけなんですね。 CPUさんは、逆に、数字にしか興味がありませんから、メモリーアドレス****と書いてくれないと困るわけです。 というわけで、機械語の世界では、メモリーの参照は全て、メモリーアドレスの絶対値が直接プログラムの中に書いてあるのが基本です。 スタック領域は、少々面倒で、関数やサブルーチンを呼び出すと別の領域を確保してあげる必要がでてくるので、このアドレスに関しては、まず、現在のスタックのベースとなるアドレスをスタックポインタと呼ばれる特殊なレジスタに設定することになっています。そして、この中のアドレスに関しては、このベースアドレスからどれだけ離れているか(オフセット)を指定することにより、メモリーアドレスの絶対値を求めます。つまり、オフセットがスタック内のメモリーアドレスの代わりをするわけです。そして、機械語の中では、このオフセットの値が直接書いてあります。 そして、CPUさんは、やっぱり、このオフセットの絶対値にしか興味がありません。オフセット***がaというローカル変数名でC言語に書かれていたことには全く興味がないのです。だから、紐づけをしておく必要は全くありません。 この紐づけは、正しい機械語を記述するために、コンパイラやリンカが必要とします。だから、コンパイラやリンカが扱うファイル群の中にこの紐づけを記述したファイルが実はあります。基本、バイナリ形式ですが、人間に見やすいように、クロスリファレンスとか、mapファイルとかいう形でテキスト化されたファイルを出力するようにもできることが多いです。デバッグするときに、メモリーアドレスを直接追いかける必要がでてきた時に、「人間が」参照することがあります。
その他の回答 (4)
- wormhole
- ベストアンサー率28% (1626/5665)
メモリに確保される場合は他の回答者が書かれていますので省略しますが、 レジスターに割り当てられる場合もあります。
- notnot
- ベストアンサー率47% (4900/10358)
プログラムの中に入っています。 ローカル変数の場合、「変数aの番地」というのは「スタックのベースポインタからのオフセット」で示されます。 ベースポインタというのは、関数に入ったときのスタック先頭を指しています。 例えば「変数aの場所は、ベースポインタ値 引く 8バイト」とかなります。 この-8という数値はコンパイル時に決まって、機械語命令の中に埋まっています。
- neKo_quatre
- ベストアンサー率44% (735/1636)
> と同時にaという変数名と確保されたスタック領域の番地を紐づけるようなメモリがどこかに確保されるのではないかと思ってるのですが、 いえ。 コンパイル、リンクされて出来た仮にtest.exeには、aという変数名の情報は残っていません。(デバッグのための情報を残す場合は別) 試しに、 ~ int b = 0; ~ ってプログラムを作成し、test2.exeを作って比較すると、同一の.exeが出来ているハズ。 最近の開発環境だと、.exeに色んな情報が付加されるので、そううまく行かないかもですが。
- kkkkkm
- ベストアンサー率66% (1719/2589)
こちらが参考になるのではないかと思います ポインタ変数の仕組み 変数とメモリの関係 https://9cguide.appspot.com/15-02.html