C++自学・自習(第6章)
第6章 配列とポインタ
- 6.4.1 malloc と free
- (プログラム例6.6) メモリの動的確保( 1 次元配列)
- (プログラム例6.7) メモリの動的確保( 2 次元配列)
- 6.4.2 new と delete
- (プログラム例6.8) メモリの動的確保( 1 次元配列,new )
- (プログラム例6.9) メモリの動的確保( 2 次元配列,new )
6.4 メモリの動的確保
- 6.4.1 malloc と free
- クラスの人数が 50 人であるとします.各人の国語,数学,及び英語の試験の点を処理するため,以下のような配列変数を定義したとします.
int a[50][3];
- クラスの人数や対象とする科目数が減少するような場合は特に問題はありませんが,増加する場合は,同じプログラムで処理できなくなります.さらに,各人の名前も記憶しておきたい場合は,別の配列を用意する必要があります.
- このような場合に対処する 1 つの方法は,printf 等のようにシステムが所有している関数 calloc や malloc を利用することです.これらの関数を利用することにより,各行毎に異なった型のデータを保存したり,また,異なったサイズの配列を定義することが可能です.なお,これらの関数を使用して確保されたメモリは,プログラムが終了するまで存在します.確保されたメモリを開放したい場合は,free 関数を使用する必要があります.ただし,領域を開放してもその領域をプログラムが有効に利用してくれるとは限りません.なぜなら,C/C++ においてはガーベッジコレクションを行ってくれないからです.したがって,頻繁に領域の確保と解放を繰り返すと,未使用の領域がふくれあがり,頻繁にスワッピングが起こったり,または,メモリが不足するような状態が発生します(下に述べる,realloc の場合も同様).できるだけ,プログラムの開始時に領域をまとめて確保し,プログラム終了時に解放されるようなプログラムを書いた方が安全だと思います.
- また,確保したメモリがプログラム実行の進展に従い不足したような場合は,realloc 関数によってメモリ領域を変更することができます.
- (プログラム例6.6) メモリの動的確保( 1 次元配列) ( A 〜 B の部分を可能な限り一つの変数,定数,演算子等で,埋めてください.その際,文字を削除してから,正しい答えを半角文字で,かつ,余分なスペースを入れないで入力してください.)
- 次のプログラムは,入力されたデータ数に応じた配列を確保し,入力されたデータをその配列に保存し,それらの和を求めています.
- (プログラム例6.7) メモリの動的確保( 2 次元配列) ( A 〜 D の部分を可能な限り一つの変数,定数,演算子等で,埋めてください.その際,文字を削除してから,正しい答えを半角文字で,かつ,余分なスペースを入れないで入力してください.)
- このプログラムでは,n 行 m 列の 2 次元配列を確保し,その中に n 人の m 科目の点数を入力しています.また,各科目ごとの平均も計算し,配列に入れています.なお,平均点を入れる配列は 0 で初期設定しています.
- 6.4.2 new と delete
- C++ では,new 及び delete 演算子を使用して,malloc や free 関数と同じように,メモリの動的確保及び解放を行うことが可能です.
- new 演算子は,データ型を与えると,例えば,
int *pi = new int;
- のように,その型のデータを記憶するのに必要な大きさのメモリを確保し,そのメモリ領域へのポインタを返します.指定した大きさのメモリを確保できないときは,0 を返します.初期設定も可能ですが,配列を与えた場合,calloc 関数のように,すべての要素を初期設定することはできません.
- delete 演算子は,new 演算子によって確保されたメモリを解放します.意図的に解放しない限り,確保されたメモリはプログラム終了時まで存在しますので,必要な場合は,例えば,
delete pi;
- のように,delete 演算子によって解放して下さい.また,new によって配列を確保した場合は,次のような delete の使用方法をして下さい.ガーベッジコレクションが行われない点は同様ですので,前節で述べましたように,確保と解放には十分注意してください.
double *dp = new double [10]; // 「10」の部分は変数でも構わない
・・・・・
delete [] dp;
- 2 次元以上の配列も同様にして確保できます.例えば,2 行 3 列(行や列の数は変数でも構わない)の配列を確保するためには,以下のように記述します.この結果,概念的には,右図に示すような領域が確保されます.
double** pd = new double* [2];
for (i1 = 0; i1 < 2; i1++)
pd[i1] = new double [3];
- また,解放するときは,以下のようになります.
for (i1 = 0; i1 < 2; i1++)
delete [] pd[i1];
delete [] pd;
- なお,realloc 関数に対応するような演算子はありません.new と delete 演算子の詳細な使用方法については,プログラム例を参考にして下さい.
- (プログラム例6.8) メモリの動的確保( 1 次元配列,new) ( A 〜 B の部分を可能な限り一つの変数,定数,演算子等で,埋めてください.その際,文字を削除してから,正しい答えを半角文字で,かつ,余分なスペースを入れないで入力してください.)
- プログラム例6.6 を new と delete を使用して書いた例です.
- (プログラム例6.9) メモリの動的確保( 2 次元配列,new) (A〜Dの部分を可能な限り一つの変数,定数,演算子等で,埋めてください.その際,文字を削除してから,正しい答えを半角文字で,かつ,余分なスペースを入れないで入力してください.)
- プログラム例6.7 を new と delete を使用して書いた例です.
-------------------------演習問題開始-------------------------
- 多次元配列,及び,メモリの動的確保を使用する問題です.malloc,または,new 演算子,いずれの方法を使用しても構いません.
-------------------------演習問題終了-------------------------