C言語での多次元配列の作成法

以下では例としてdouble型を扱っています。

2次元

mallocを複数かます

array[N][M]で参照できるようにしたい。 イメージ: まず、N個の長さのポインタの配列をとる。 次に、N*M個の長さのdoubleの配列をとる。 M個ごとにarray[i]のポインタを当てることで、1次元にデータを確保しながら参照はarray[i][j]でできるようになる。

作成する関数と解放する関数を書いておきます。

double **d2array(int row, int column){
    /*
    matrix[i][j]で参照できる行列(ポインタ)をreturnする関数
    初期化はしていない。メモリを連続的に当てている。
    この操作ではなんどもポインタを使っているので注意。
    matrix[0]もポインタ。
    printf("%p\n",matrix[0]);とかで確認できる
    使い方:
        double **mat;
        mat = d2array(n ,m);
    */
    double **matrix;
    int i;
    matrix = (double**) malloc(row*sizeof(double*));
    if(matrix == NULL){
        printf("d2arrayメモリが確保できません\n");
        exit(1);
    }
    matrix[0] = (double *) malloc(row * column * sizeof(double));
    if(matrix[0] == NULL){
        printf("d2array[0]メモリが確保できません\n");
        exit(1);
    }
    for(i=0; i<row; i++){
        matrix[i] = matrix[0] + i * column;
    }
    return matrix;
}

/*2次元配列の解放*/
void d2free(double **array){
    free(array[0]);
    array[0] = NULL;
    free(array);
    array = NULL;
}

staticな配列を利用する

片方の方向をstaticにとることで高速化します。

array = (double (*)[N])malloc(sizeof(double[N])*M);

3次元以上

mallocを複数かますやり方しか知りません。

double ***d3array(int row, int column, int depth){
    double ***matrix = (double***)malloc(row*sizeof(double**));
    if(matrix == NULL){
        printf("d3arrayメモリが確保できません\n");
        exit(1);
    }
    matrix[0] = (double**)malloc(row*column*sizeof(double*));
    if(matrix[0] == NULL){
        printf("d3array[0]メモリが確保できません\n");
        exit(1);
    }
    matrix[0][0] = (double*)malloc(row*column*depth*sizeof(double));
    if(matrix[0][0] == NULL){
        printf("d3array[0][0]=%d %d %dメモリが確保できません\n", row, column, depth);
        exit(1);
    }
    for(int i=0; i<row; i++){
        matrix[i] = matrix[0] + i*column;
        for (int j=0; j<column; j++){
            matrix[i][j] = matrix[0][0] + i*(column*depth) + j*depth;
        }
    }
    return matrix;
}
/*3次元配列の解放*/
void d3free(double ***array){
    free(array[0][0]);
    array[0][0] = NULL;
    free(array[0]);
    array[0] = NULL;
    free(array);
    array = NULL;
}

C++で作成するとき

newを使ってあげましょう。2次元配列は以下のような感じ。

double **d2array(int row, int column){
    double **matrix;
    int i;
    matrix = new double* [row];
    if(matrix == NULL){
        printf("d2arrayメモリが確保できません\n");
        std::exit(1);
    }
    matrix[0] = new double [row * column];
    if(matrix[0] == NULL){
        printf("d2array[0]メモリが確保できません\n");
        std::exit(1);
    }
    for(i=0; i<row; i++){
        matrix[i] = matrix[0] + i * column;
    }
    return matrix;
}
/*2次元配列の解放*/
void d2free(double **array){
    delete [] array[0];
    array[0] = NULL;
    delete [] array;
    array = NULL;
}