2017-11

スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

二次元配列の動的な割り当て方

int table[3][4] みたいな二次元配列を動的に割り当てる方法を調べたら以下の方なやり方を見つけた。(BorlandのQ&A)
int x = 4;
int y = 3;
int **table = (int **)malloc(sizeof(int *) * y);
for(i = 0; i < y; i++){
    table[i] = (int *)malloc(sizeof(int) * x);
}

 しかし、この方法を使うと table[0][3] と table[1][0] の間が連続ではなくなってしまい、
for(j = 0; j < y; j++){
    for(i = 0; i < x; i++){
        table[j][i] = i + (j*x);
        printf("%d\n", *((*table) + i + (j*x)));
    }
}

のようにした場合に、p[j][i]に値は入るのですが、*((*p) + i + (j*4))では同じ位置を指してくれません。ってことになる。

 そこで、次のようにすると連続でちゃんと使えるようになる。
int **table = (int **)malloc(sizeof(int *) * y); 
int *tableY = (int *)malloc(sizeof(int) * x * y); 
for (i = 0; i < y; i++) table[i] = tableY + i * x; 

/* 処理 */

free(*table);
free(table);

 せっかくだからこれを関数化して使いたいと思ったけど、C言語のみだと型ごとに作らないとダメっぽい。
しょうがないのでC++で作ると次のようになる。テンプレート使って結構すっきり。
//2次元配列を動的に取る
template <typename MYTYPE> MYTYPE **new2(size_t y, size_t x) 
{
    MYTYPE **p = new MYTYPE *[y]; 
    MYTYPE *pY = new MYTYPE[x * y]; 
    for(int i = 0; i < y; i++) p[i] = pY + i * x; 
    return p;
}

//2次元配列を開放
template <typename MYTYPE> void delete2(MYTYPE **pp)
{
    delete[] *pp;
    delete[] pp;
}

int main()
{
    int **p1 = new2<int>(34);//int p1[3][4]を動的に取る

    /* 処理 */

    delete2(p1);//p1開放


    double **p2 = new2<double>(59);//double p2[5][9]を動的に取る

    /* 処理 */

    delete2(p2);//p2開放


    return 0;

 注意することは**new2(size_t y, size_t x)なので、**p1 = new2(3, 4)としたときにはp1[3][4]の配列を確保したことになる。new2(y, x)のときp[y][x]。これは外側(x側)が先に回るためこうした。引数と配列の縦横の関係を間違えないように!

 もしかしたらC++だともっと楽に出来る一般的な方法があるのかもしれないけどこんな感じで・・・
スポンサーサイト

コメント

コメントの投稿


管理者にだけ表示を許可する

トラックバック

http://ku470.blog68.fc2.com/tb.php/10-b66c1e14
この記事にトラックバックする(FC2ブログユーザー)

«  | HOME |  »

プロフィール

ku_470

Author:ku_470
HP

FLVP (FLVプレイヤー)
Vector
説明

カテゴリー

最近の記事

最近のコメント

最近のトラックバック

FC2カウンター

リンク

上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。