連載の7回目から,ポインタを使ってメモリーを操作するプログラミングの解説をしてきました。ポインタ編3回目となる今回は,動的なメモリーの確保を中心に多次元配列をポインタで扱う方法などについて説明します。いかにも難しそうな内容です。一気にすべてを理解しようとすると辛いかもしれませんが,なるべく小さな単位に分解して,小さな「わかった」を積み上げていけば理解できるように進めていきたいと思います。ですから,「パス!」などと読み飛ばさずに,じっくりとお付き合いくださいね。

なぜ,動的なメモリーの確保が必要なのか?

 メモリーを固まりとして,つまりメモリーのブロックとして確保する方法は,本連載の第5回で紹介した配列です(リスト1)。

 int tensu[5];

と定義するとint型の要素を5個持つ配列が作成されます。この配列には,例えば英語の点数を5人分,それぞれtensu[0]~tensu[4]に格納することができます。

リスト1●配列を利用して,5人分の点数を入力し,平均点と最高点を求めるプログラム
リスト1●配列を利用して,5人分の点数を入力し,平均点と最高点を求めるプログラム

 配列にすると,以下に示すコードのようにそれぞれの値をまとめて扱うことができるので,変数をそれぞれ定義するより便利なのでしたね。

 for (i = 0; i < 5; i++) {
  goukei += tensu[i];
 }

リスト1では,(1)で5人分の点数を入力する処理を,(2)で平均点と最高点を出力する処理を記述しています。

 しかし,配列の要素数はプログラムを書いた時点,プログラムをコンパイルした時に決まってしまいます。プログラムの実行時に配列の要素数を変更することはできません。ですから,配列は静的なメモリーのブロックを確保する方法と言えます。

 ここで,学校の授業で選択制の科目を履修するイメージを描きましょう。例えば「プログラミングの基礎」という科目があって,定員は40名とします。期末にはテストを行うので,生徒の点数の平均や最高点を求めるプログラムを用意しておきたいとします。

 int tensu[40];

 通常,このように定員40人分の配列を定義して点数を格納できるようにします。しかし,年度によっては20名しか選択しないこともあれば,41名希望があって,1人ぐらいなら,なんとか追加しようと融通をきかすこともあるかもしれません。20名しかテストを受けない場合は,tensu配列の半分はムダです。本連載で使っているBorlandC++コンパイラ*1ではint型は4バイトを使って値を記録しますので,4バイト×20人で80バイトのムダです。もちろん,現在のPCには256Mバイト以上のメモリーが搭載されていることが多いので80バイトを気にすることはありませんが,これが数万人のデータを扱うプログラムだったら,気になりますね。それに定員40名のところを,なんとかして41名まで受け入れた場合,tensu[40]の配列に41人目のテストの結果を格納できるわけもなく,「コンピュータは融通がきかない」なんて話になってしまいます。

 Visual BasicだとRedim命令などで配列のサイズを変更することもできるのですが,そうでないCなどの言語の場合,常に最大サイズを予想して配列を用意しなければなりません。「多くても50人くらいでしょう」と言われても,心配性なプログラマは,もうちょっと余裕をみて60の要素を持つ配列を作ってしまうかもしれませんね。料理だと少し足りないぐらいがおいしく食べられる量かもしれませんが,配列は足りないと,どうしようもありません。かといって余裕をみると,いつも余ってしまいます。配列というのはどうも悩ましいもののようです。

 必要なサイズのメモリー・ブロックを,ムダを出さずに必要なときに確保するにはどうしたらいいか。それが「動的なメモリーの確保」です。以下で紹介していきます。