第八回-03 メインメモリとアドレス


変数のアドレスを知ろう

これまで、プログラムにおいて「変数」というものを何度も扱ってきた。
変数を簡単に言い替えると「入れ物」ということができる。 「int x;」であれば、「整数を格納する入れ物 x」というわけである。

では、「入れ物」の実体はどこにあるのかというと、実はメモリ上にある
これまで、何気なく使って来た変数であるが、全てメモリ上に配置されていた、というわけである。

それを確認するために、以下のプログラムを記述して実行してみよう。
最後の数行以外は難しいことは何もない。 int 型の整数 x, y を宣言し、x に 5 を、y に x の値 (つまり 5) を格納しているだけである。

なお、ここでは main 関数の中で変数 x, y を宣言しているが、このように関数内で宣言される変数を正式には自動変数と呼ぶ。



上記のプログラムを実行するには、「第一回-03 初めての C/C++ プログラミング(コンソールアプリケーション編)」を参考に
コンソールアプリケーションのプロジェクトを作成し、冒頭に

#include <iostream>

を記述してから main 関数内にプログラムを記述すれば良い。今回学んだタブによる字下げにも注意を払うこと!

「return 0;」の手前の2命令 (以下に再掲) に、今回新しく学ぶ内容が含まれている。

std::cout << "xのアドレスは" << &x << "です\n";
std::cout << "yのアドレスは" << &y << "です\n";


ここでみられる &x、&y に注目して欲しい。これらは以下の意味がある。 つまり、変数の前に & をつけると、その変数のメモリ上のアドレスが返される、というわけである。
さて、それでは実際に動作を確認してみよう。正しく記述できると以下のようになる。



x と y の値が 5 であるのは問題ないであろう。その次のアドレスであるが、 メモリアドレスは 16 進法で表されているので注意が必要である。

この場合知っておく必要があるのは、16 進法では と数が増えるということである。

上の結果に基づき、メモリ上の x と y の配置を表したのが以下の図である。



この図で注目すべきポイントをまとめると以下のようになる。 上記の二つの項目は、多くのシステムで共通なので知っておくべきである。

次に、やや細かな話だが、いくつか補足。

まず、変数がメモリ上で詰まって配置されずに間をあけて配置されているのは、 これは Debug ビルドだからである。
Debug ビルドでは、プログラム中の間違い (バグ) の発見のために、コンパイラが幾つか命令を追加したり、
メモリを補助的な情報の配置に使ったりする。

一方、下図のように、Debug ビルドから Release ビルドに変更すると、デバッグのための情報は追加されず、
さらにプログラムの最適化も行われ、プログラムの動作が速くなる。
ただし、最適化により、変数の配置の順番がコンパイラにより入れ換えられる、などのことも起こる。
上の箇条書きで「(原則的に) スタックの高位アドレス側から…」と書いたのはそのためである。

いずれにせよ、変数をメモリ上にどう配置するかはコンパイラの仕事なので、任せておけば問題はない
しかし、変数 (今回学んだのは自動変数と呼ばれるもの) がメモリに配置されるイメージを掴むことは大変重要である

次回以降も引続きこの内容で学習を進める。







←第八回-02 メインメモリとは何か第八回課題→

非情報系学生のための C/C++ 入門に戻る