/*
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;
}