二次元配列の動的確保について

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
しろ

二次元配列の動的確保について

#1

投稿記事 by しろ » 15年前

こんにちは。いつもお世話になります。早速ではありますが、「ポインタの極意」(柴田望洋)のP268にある以下のプログラムをご覧ください。
------------------
#include <stdio.h>
#include <stdlib.h>

int main(void){

    int df;
    int height;
    int (*p)[3];

    scanf("%d",&height);

    p=(int (*)[3])calloc(height*3,sizeof(int));

    if(p==NULL)
        printf("失敗\n");
    else{
        int i,j;

        for(i=0;i<height;i++)
            for(j=0;j<3;j++)
                p[j]=0;
        for(i=0;i<height;i++)
            for(j=0;j<3;j++)
                printf("p[%d][%d]=%d\n",i,j,p[j]);
        free(p);
    }

    return 0;
}


------
のピープ領域を確保するp=(int (*)[3])calloc(height*3,sizeof(int))の部分の引数を

p=(int (*)[3])calloc(height*3,sizeof(*p))
p=(int (*)[3])calloc(height,sizeof(int (*)[3]))

と変更したとき、上は問題ないのですが、下についてはpを解放する時点でエラーが発生します(確保する時点では問題なく動作します)。確保している領域は変わらないと思うのですが、なにがまずいのか、教えていただけると助かります。よろしくお願いいたします。

しろ

Re:二次元配列の動的確保について

#2

投稿記事 by しろ » 15年前

すいません。よくよく考えてみたら

p=(int (*)[3])calloc(height,sizeof(int (*)[3])) というのは

p=(int (*)[3])calloc(height,sizeof(p))

と同じになってしまうので、駄目ですよね。一応この解釈で正しいか、教えていただけると助かります。 よろしくお願いいたします。

うしお

Re:二次元配列の動的確保について

#3

投稿記事 by うしお » 15年前

ちょっと趣旨とずれていたらすみません

二次元配列の動的確保が、xとy両方を動的に確保するのでしたら、

#include <stdlib.h>
#include <stdio.h>
int main(){
int *pArray2D = 0;

int Width = 5;
int Height = 10;

int x = 0;
int y = 0;
pArray2D = (int*)malloc(sizeof(int) * Width * Height);

for(y = 0 ; y < Height ; ++y)
{
for(x = 0 ; x < Width ; ++x)
{
//アクセス
pArray2D[y*Width + x] = y*Width + x;//ためしにインデックスを代入してみる
printf("%d,",pArray2D[y*Width + x]);
}
printf("\n");
}
free(pArray2D);
return 0;
}

このようなシンプルな形になる気がするのですが、どうでしょう?

うしお

Re:二次元配列の動的確保について

#4

投稿記事 by うしお » 15年前

追加ですが、

int (*p)[3];
は、
int *p;の配列なので、

p[0] = (int*)calloc(height,sizeof(int));
p[1] = (int*)calloc(height,sizeof(int));
p[2] = (int*)calloc(height,sizeof(int));

このようにしたかったのではないか?と思いました



画像

初級者

Re:二次元配列の動的確保について

#5

投稿記事 by 初級者 » 15年前

>int (*p)[3];
>は、
>int *p;の配列なので、

これは間違い。

>int (*p)[3];

は、「pは要素数3の配列へのポインタ」と読みます。

>int *p;の配列なので、

要素がポインタである配列は、例えば
int *p[3]
のように書きます。
()のあるなしで、「配列へのポインタ」と「ポインタの配列」となり、
意味が全然違います。

うしお

Re:二次元配列の動的確保について

#6

投稿記事 by うしお » 15年前

>>初級者さん(これ名前であってますよね?

>int (*p)[3];

>は、「pは要素数3の配列へのポインタ」と読みます。
あ、そうだったんですね!勘違いしていました、ありがとうございました。

int Array[3];
int (*p)[3] = &Array;
こういうことでしたか!
勉強になりました

しろ

Re:二次元配列の動的確保について

#7

投稿記事 by しろ » 15年前

お返事が遅くなりまして申し訳ありません。

>うしお様

本論とはそれてしまうのですが、
int *pArray2D = 0;
というのはOKなのでしょうか?

それとも0はint型の0ではなく、(void *)0あるいは(int *)0と同一視していいということでしょうか?


しろ

Re:二次元配列の動的確保について

#9

投稿記事 by しろ » 15年前

なるほど、そうでしたか。

とりあえず掲題の件については、解決したので「解決」とさせていただきます。
皆様どうもありがとうございました。

閉鎖

“C言語何でも質問掲示板” へ戻る