配列の動的な確保

2006/1/31更新

プログラムを実行時に、扱う問題のサイズなどがはじめて明らかになることが あると思います。そのような場合には、前もって使用するデータを 配列として定義できません(実はC言語の新しい仕様「ISO/IEC 9899:1999 - Programming Language C」(略称 C99) では可能ですが、慣れるまでは 使わないことをお勧めします)。かといって、どのような問題にも十分な サイズの配列を確保しておくのは、メモリーの無駄遣いになりますので お勧めしません。そのような場合には、 このページで紹介するような動的な領域確保を行うようにしてください。
構造体の配列についてはこちら

プログラム例

#include <stdio.h> #include <stdlib.h> int malloc_1dim(int **array, int length){ // 1次元配列の確保 if(NULL == (*array = (int *)malloc(sizeof(int)*length))){ exit(-1); } return 1; } int malloc_2dim(int ***array, int row, int column){ // 2次元配列の確保 int i, j; if(NULL == (*array = (int **)malloc(sizeof(int)*row))){  exit(-1); } for(i=0;i<row;i++){ if(NULL == ((*(*array+i)) = (int *)malloc(sizeof(int)*column))){ exit(-1); } // 2段階で領域確保する必要のあることに注意!! } return 1; } void free_1dim(int *array){ // 1次元配列の領域解放 free(array); } void free_2dim(int **array, int row){ // 2次元配列の領域開放 // 2段階でfreeする必要のあることに注意!!  int i; for(i=0;i<row;i++){ free(array[i]); // free(*(array+i))と同じ意味 } free(array); } main(){ int i, j; int r = 10; int c = 5; int *one_dim; int **two_dim; malloc_1dim(&one_dim, c); malloc_2dim(&two_dim, r, c); for(i=0;i<c;i++){ one_dim[i] = i*10; printf(" %d ",one_dim[i]); } printf("\n"); for(i=0;i<r;i++){ for(j=0;j<c;j++){ two_dim[i][j] = i*10+j; printf(" %d ",two_dim[i][j]); } printf("\n"); } free_1dim(one_dim); free_2dim(two_dim, r); }

2次元配列を確保する関数の場合、ポインタのポインタのポインタ変数で処理が進むことに 注意して下さい。また、2段階で確保・解放する必要があることに注意。

プログラム例 2 確保した領域へのポインタ(のポインタ)変数を返す方法

また、以下のように関数の返り値を使って、確保した領域を指すポインタ (もしくはポインタのポインタ変数)を返すようにする方法もあります。 以下の赤で強調した部分が、主に変更された部分です。
#include < stdio.h > #include < stdlib.h > int *malloc_1dim(int length){ // 1次元配列の確保 int *a; if(NULL == (a = (int *)malloc(sizeof(int)*length))){ exit(-1); } return a; } int** malloc_2dim(int row, int column){ // 2次元配列の確保 int i, j; int **a; if(NULL == (a = (int **)malloc(sizeof(int)*row))){ exit(-1); } for(i=0;i<row;i++){ if(NULL == ( a[i] = (int *)malloc(sizeof(int)*column))){ exit(-1); } // 2段階で領域確保する必要のあることに注意!! } return a; } void free_1dim(int *array){ // 1次元配列の領域解放 free(array); } void free_2dim(int **array, int row){ 2次元配列の領域開放 // 2段階でfreeする必要のあることに注意!! int i; for(i=0;i<row;i++){ free(array[i]); // free(*(array+i))と同じ意味 } free(array); } main(){ int i, j; int r = 10; int c = 5; int *one_dim; int **two_dim; one_dim = malloc_1dim(c); two_dim = malloc_2dim(r, c); for(i=0;i<c;i++){ one_dim[i] = i*10; printf(" %d ",one_dim[i]); } printf("\n"); for(i=0;i<r;i++){ for(j=0;j<c;j++){ two_dim[i][j] = i*10+j; printf(" %d ",two_dim[i][j]); } printf("\n"); } free_1dim(one_dim); free_2dim(two_dim, r); }