/* C言語/C++言語で2次元配列を動的に確保&解放するプログラム 2次元配列を使うとき、 double a[U][V]; と固定的に宣言すると、U,V は定数でなければなりません。 一方、このページの ALLOC_MATRIX マクロを使って、 double**a=ALLOC_MATRIX(double,u,v); と書くと、u,v の実行時の値に応じて、動的に配列が確保されます。 データへのアクセスは、固定的に宣言した場合と同じように、 x=a[i][j]; のように記述できます。例えば、 double**a=ALLOC_MATRIX(double,3,4); とした時のメモリのイメージは以下の図のようになります。 (■はdoubleへのポインタ。□はdouble。) ポインタ部 データ部 a → ■ → □□□□ ■ → □□□□ ■ → □□□□ ALLOC_MATRIX マクロは、ポインタ部とデータ部をまとめて malloc または new で確保するので、不要になったら単に free(a); または delete[]a; とするだけで全て解放されます。 メモリの確保に失敗した時、ALLOC_MATRIX マクロは 0 を返します。 このマクロは double の配列に限らず他の型でも使えます。例えば char**a=ALLOC_MATRIX(char,u,v); のようにしても正しく動作します。 */ #include <stdio.h> #include <stdlib.h> #ifdef __cplusplus template<typename T>T**AllocMatrix(int u,int v) { int i; T**a,*b; try { a=(T**)new char[(sizeof*a+sizeof*b*v)*u]; } catch (...) { a=0; } if (a) b=(T*)(a+u); else return 0; for (i=0;i<u;i++,b+=v) a[i]=b; return a; } #define ALLOC_MATRIX(T,U,V) AllocMatrix<T>(U,V) #define FREE(X) delete[]X #else void*AllocMatrix(int s,int u,int v) { int i,t=s*v; char**a,*b; a=(char**)malloc((sizeof*a+t)*u); if (a) b=(char*)(a+u); else return 0; for (i=0;i<u;i++,b+=t) a[i]=b; return a; } #define ALLOC_MATRIX(T,U,V) (T**)AllocMatrix(sizeof(T),U,V) #define FREE(X) free(X) #endif int main(void) { int u=14,v=13,i,j; double**a=ALLOC_MATRIX(double,u,v); for (i=0;i<u;i++) for (j=0;j<v;j++) a[i][j]=i+j/100.0; for (i=0;i<u;i++) { for (j=0;j<v;j++) printf(" %05.2f",a[i][j]); printf("\n"); } FREE(a); return 0; }