int a[20];それでは、いくつかのint型の値を格納できる配列aを作成する場合、どうすればいいでしょうか?
そこで、仮に多めに確保することにして
int a[100];と宣言したとします。これで取りあえず、100個のint型の値が格納できるようになりました。でも、実際には101個の値を格納しなければならないかもしれません。逆に格納する値がわずか2個だけだったとしたら、残る98個の配列に割り当てられたメモリが無駄になってしまいます。
そういった時に用いるのが、標準ライブラリのmalloc関数とfree関数(あ。取りあえずコイツら)です。超簡単に説明すると、mallocで必要なメモリの領域を動的に確保して、使い終わったらfreeでその領域を解放する、といった感じです。それでは実際に、この方法で101個のint型の配列に必要なメモリ領域を(mallocで)動的に確保して、そしてそれを(freeで)開放するプログラムを作成してみることにします。
#include<stdio.h>
#include<stdlib.h>
main(){
int *a;
a=malloc(sizeof(int)*101);
/* ここに実際の処理が入る */
free(a);
}
まず注目すべき点は、ヘッダファイルstdlib.hがインクルードされていることです。この中で、malloc関数は以下のように宣言されています。
void *malloc(size_t);
とりあえず、戻り値の型がvoid型へのポインタ(void *)であることと、仮引数が受け取るのは必要なメモリ(バイト)であることを覚えておいて下さい。
また、ついでにfree関数の方も確認しておきます。
void free(void *);
int *a;
そしてその次の行で、malloc関数の戻り値(確保した領域の先頭アドレス)が、先程のint型変数のポインタaに代入されています。
a=malloc(sizeof(int)*101);
malloc関数の戻り値がvoid型へのポインタであるのに対して、その値を代入するポインタaはint型変数のポインタです。一見、型が合わないように思えますが、ANSI規格のC言語では、malloc関数の戻り値の型は、void*から自動的に必要なポインタ型に変換されるのです。
a=(int *)malloc(sizeof(int)*101);
といった具合に型キャスト(って、まだ学んでいないか・・・)すればいいと思います。型キャストについては後々学ぶことにしましょう。a=malloc(202);
とするのは止めてほしいということです。と、いうのは、型のサイズは機種によって違う場合があるからです。必ずしもchar型は1バイト、int型は2バイトではありません。で、そういう時は、前回登場したsizeof演算子を使います。この演算子はサイズをバイト数で返します。つまりint型の配列101個のサイズは、sizeof(int)*101といった方法で求めるようにして下さい。
そして割り当てたメモリを開放したい時(っていうか、使い終わったら必ず開放して下さい)は、
free(a);
と書けばいいです。
#include<stdio.h>
#include<stdlib.h>
main(){
int *a;
/* 型キャストしておいた:-) */
a=(int *)malloc(sizeof(int)*3);
a[1]=2;
a[2]=3;
a[0]=a[1]+a[2];
printf("%d\n",a[0]);
printf("%d\n",*(a+1)); /* a[1]と同じ */
free(a);
}
実行結果は、5 2つづく。