第九回-01 スタック領域上での配列の配置

第八回-03 メインメモリとアドレスで、main 関数内で定義される変数 (自動変数と呼ばれる) が
メインメモリ (特に論理メモリ) のスタック領域でどのように配置されるかを学んだ。

変数がメモリ上に配置されること、そしてスタック領域では
原則として高位アドレスから低位アドレスに向かって変数が配置されることがわかった。
(「原則として」と書いたのは、コンパイラが最適化の際に変数の順序を入れ換えて配置することがあるため)

その内容に引き続く形で、本ページでは main 関数内で配列を宣言した際の メモリ上での配置のされ型について学ぼう。
前回の講義の内容を前提として進んでゆく。


まずはプログラムを書くことから

では、配列を用いた際のメモリ配置を学ぶため、配列を用いたプログラムを書く必要がある。
以下の例を記述してみよう。これは main 関数の中身だけを記述してある。



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

#include <iostream>

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

配列については覚えているだろうか。忘れている場合は第六回-01 配列の基礎を復習して欲しいが、ポイントは 正しく記述できていれば、実行すると以下のようになる。まずここまでをクリアして欲しい。




次に配列のメモリ上の配置を知ろう

上のプログラムが正しく動いたら、次は変数 x、y、array[0]~array[4] の メモリ上でのアドレスを調べてみよう。
具体的には以下の命令を末尾に追加することになる。

変数のアドレスを知るには、変数の前に & をつければ良いことは第八回-03 メインメモリとアドレスにて学んだ。



ちなみに、& でアドレスを取り出せる、ということを覚えるために「でアドレス」という語呂合わせをするとよい、
ということを私がはじめてプログラミングを学んだ教科書に書いてあった。
下手な語呂合わせのように思えるが、未だにそれを覚えているところを見るとそれなりに効果はあるのだろう。
(ちなみにこれと対になる語呂合わせ「リスクで値」というのはポインタを学ぶ次回で出て来る予定)

なお、「& でアドレスを取り出せる」というのは C/C++ では有効であるが、その後に登場した Java/C# では使えない。
なぜ使えないようになったか、はその言語の設計思想にも関わることであるが、ポインタについて学ぶ際にいずれ話す機会があると思う。

さて、正しく記述できると、結果は以下のようになる。実際のアドレスは使っている OS やコンパイラの環境などにより異なるかもしれない。
(コンパイラ依存環境依存、などという)





(演習)
実際に表示されたアドレスを元に、x、y、array[0]~array[4]のスタック領域上の配置を図示してみよ。
第八回-03 メインメモリとアドレスを参考にするとよい。


解答はこちら

なお、配列 array[] の先頭のアドレスを &array[0] で取り出せることが上でわかったわけだが、
これを array と書いても取り出せることは知っておくと良いだろう。 つまり、以下の 2 行は同じ意味と結果を持つ、ということである

std::cout << "配列 array の先頭アドレスは" << &array[0] << "です\n";
std::cout << "配列 array の先頭アドレスは" << array << "です\n";




←第八回課題第九回-02 関数内の変数のメモリ配置→

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