メモリの動的確保
変数の型はサイズが決まっています。
また、変数の集合である配列も要素数を最初に決めなければなりません。
すなわちこれらは指定した容量のメモリを確保しています。
データの数が決まっていればその分だけ宣言すれば良いですが、要素数がわからなければそれは出来ません。
配列であれば最大値を基準に多めに確保するという方法もありますが、多すぎたり少なすぎたりとあまり良いプログラムとは言えません。
この問題の解決法として、C言語にはメモリの動的確保の機能が備わっています。
動的確保とは、好きなタイミングで好きにメモリの確保や解放が出来るということです。
malloc()、free()
ここでメモリの動的確保に必要な2つの関数を紹介します。
これらの関数はstdlib.hにて定義されているのでこれのインクルードが必要です。
malloc()
malloc(【メモリサイズ(バイト)】)
で指定したサイズのメモリを確保します。
簡単に見えますがいくつか注意点があります。
まず、malloc()で確保したメモリには変数や配列と違い型の指定がありません。
なのでキャストして使う必要があります。
基本的には使いたい型のポインタ型で指定します。
また、メモリサイズはバイト数で指定します。
そのため配列の要素数として指定する場合各変数のサイズが必要になります。
free()
free(【アドレス】)
で指定したアドレスを開放します。
普通の変数や配列はスコープから出た時に自動で確保したメモリが解放されますが、malloc()ではそれができません。
そのためfree()で解放する必要があります。
ただしプログラム終了時であれば自動で解放してくれます。
サンプルコード
注意点を見てもわかりにくいでしょう。 実際に例を見て理解しましょう。
malloc_free_sample.c
#include <stdio.h> #include <stdlib.h> int main(void) { int size; int *arr; int i; printf("要素数:"); scanf_s("%d", &size); arr = (int *)malloc(size * sizeof(int)); for (i = 0; i < size; i++) { arr[i] = i * i; printf("arr[%d] = %d\n", i, arr[i]); } free(arr); return 0; }
scanf_s()で指定した要素数の配列を定義し、それに添え字の2乗を代入し表示するプログラムです。
int *arr
で用意したint型のポインタに
arr = (int *)malloc(size * sizeof(int))
で確保したメモリのアドレスを代入しています。
今回はint型なので(int *)でキャストし、size個のint型の変数を用意するのでsizeとint型のバイト数を返すsizeof(int)を乗算しています。