動的配列
動的に領域を確保する方法として「malloc()」を使用した方法があります。
「malloc()」は構造体の領域を動的に確保したり、実行するまで、どのくらいの大きさの領域を
確保したらいいのか?不明な場合に用います。
そしてさらに、指定した領域では不足するため、領域を追加する方法として
「realloc」が用意されています。
この「realloc」を使用することにより、領域を拡張することができます。
動的にメモリを割り当て、任意のタイミングで解放できる領域をヒープといいます。
この「ヒープ」で動的領域を管理します。
また、「malloc()」を使用した後はメモリの解放処理をすることになります。
メモリの解放には「free」を実行することになります。
reallocの使い方 | p=realloc(p, sizeof(型) * size ); |
|
mallocおよびreallocを使用した場合、配列の要素数はプログラム内で別途管理する必要があります。
また、VisualStudio C++のケースでは
mallocおよびreallocで配列の領域を確保する際、データ宣言をmallocおよびreallocの前に
つけてください。
(例) | array = (int*)malloc( sizeof( int ) * 2 ); | array = (int*)realloc( array, size ); |
|
このサンプルでは次の種類について見ていきます。
No | ケース | (1) | 数字のケース | (2) | 文字列のケース | (3) | typedefを使用したケース |
それではサンプルを見てください。
数字のケースから見てみます。
22~57行目までが数字の動的配列のサンプルです。
25行目を見ると使用する変数を数字型のポインタで表しています。
そして30行目を見てください。「malloc」を使い、数字型の領域を作っています。
配列 = (int*)malloc( sizeof ( int ) * 大きさ );
|
VisualC++では「malloc」の前に「(int*)」を宣言してください。
このサンプルでは大きさを2としているので2個分の領域を取っています。
そして、さらに配列の大きさを拡大するのですが、その前に、拡大前のデータが正しく残っているかどうか?を知るために36~38行目のように配列にデータを格納しておきます。
次に「realloc」を用いて先ほど領域を確保した配列をさらに拡大してみます。
45行目を見ると「realloc」を使って領域の拡大をしています。。
配列 = (int*)realloc( 配列, sizeof ( int ) * 大きさ );
|
この「realloc」は既存の配列を変更しないで拡張部分を空データで追加してくれます。
このサンプルでは2個の領域から3個の領域に増やしています。
すなわち、1個分増やしているのですね。47行目で3個目(配列の添え字は「0」から始まります)に30と値を格納しています。
結果を確認しているところが49~52行目となります。
さいごに、配列を「malloc」および「realloc」で拡張した場合はメモリの解放をしてください。
方法は「free」を実行させます。55行のようにfreeに配列として用いた変数を設定します。
次に文字列のケースについて見てみます。
58~93行目が文字列のサンプルとなります。
配列として使用するため61行目のようにポインタ「*」を重ねて宣言しています。
数字のケースと同じように最初に2個分の領域をとっているのが66行目です。
配列 = (char**)malloc( sizeof ( char* ) * 大きさ );
|
このように宣言の箇所が「int*」と「char**」というように型の指定方法が違うだけで考え方は同じです。
また「realloc」で配列を拡張知る場合も型の指定方法が違うだけとなります。
配列 = (char**)realloc( 配列, sizeof ( char* ) * 大きさ );
|
さいごに「typedef」を組み合わせた方法について見てみます。
「typedef」で構造体(struct)を用いると配列の1要素に各値を持たせることができます。
このサンプルでは本の情報として書名と価格を使っています。
それを表しているのが97~101行目となります。
このtypedefで宣言したリストを配列して宣言しなおしているのが103行目です。
また、上記のサンプルと同様に「malloc」で領域を111行目のように確保しています。
ここでは型宣言のところが「typedef」で宣言した101行目の「data」としています。
配列 = (typedefで宣言した変数名*)malloc( sizeof ( typedefで宣言した変数名 ) * 大きさ );
|
あとは数字や文字列のケースと同様です。
拡大する「realloc」の場合も型のところが違ってくるだけです。
配列に「配列[添え字].要素1」、「配列[添え字].要素2」…というように使えるとプログラムの書き方もバリエーションが増え、楽になると思います。
さいごにfreeをするのを忘れないようにしてください。
サンプルプログラムを実行した結果です。
|
|