No.1618![]() |
動的に確保された複数の領域は配列なのか? 投稿者---Misae(2004/04/28 20:10:00) |
||
動的に確保された領域は配列のように連続しているのでしょうか? 以下のコードのような配列の添字によるアクセスは正しいでしょうか? #define MAX 5 /* 中略 */ int *n=NULL; int i; /* MAX個のint型の領域を確保して * その先頭の要素へのポインタを返す */ n=(int*)calloc(MAX,sizeof(int)); /* 適当な値を代入 */ for(i=0;i<MAX;i++) n[i]=i+10; // 添字による各領域へのアクセス また、次のコードとどう違うのでしょうか? int (*n)[MAX]; // 配列へのポインタ int i; /* MAX個のint型の配列の領域を確保して * その先頭の用へのポインタを返す */ n=(int (*)[MAX])calloc(MAX,sizeof(int)); /* 適当な値を代入 */ for(i=0;i<MAX;i++) *n[i]=i+10; // 添字による各領域へのアクセス |
No.1619![]() |
Re:動的に確保された複数の領域は配列なのか? 投稿者---たか(2004/04/28 20:32:22) |
||
>動的に確保された領域は配列のように連続しているのでしょうか? >以下のコードのような配列の添字によるアクセスは正しいでしょうか? /* MAX個のint型の領域を確保して * その先頭の要素へのポインタを返す */ n=(int*)calloc(MAX,sizeof(int)); /* 適当な値を代入 */ for(i=0;i<MAX;i++) n[i]=i+10; // 添字による各領域へのアクセス calloc()で要求されたメモリブロックは、calloc()関数がNULLを返さない 限り、連続していて、しかも中身が0でクリアされています。NULLを返した 場合は連続したメモリブロックの確保に失敗した事を示し、その場合は ブロックが確保されていませんので使ってはなりません。 >また、次のコードとどう違うのでしょうか? int (*n)[MAX]; // 配列へのポインタ int i; /* MAX個のint型の配列の領域を確保して * その先頭の用へのポインタを返す */ n=(int (*)[MAX])calloc(MAX,sizeof(int)); /* 適当な値を代入 */ for(i=0;i<MAX;i++) *n[i]=i+10; // 添字による各領域へのアクセス これは、間違っています。int (*n)[MAX]は、nが int [MAX]で表される 一次元配列へのポインタという意味になり、n+1はnにMAX * sizeof(int) が足され、すなわちcalloc()で確保したメモリブロックの範囲を飛び出し てしまいます。n == 0の時にのみ安全です。その場合はn[0][0]にアクセス しているのと同じです。n == 1だとn[1][0]にアクセスしている事になり ます。 |
No.1632![]() |
Re:動的に確保された複数の領域は配列なのか? 投稿者---Misae(2004/05/04 14:01:08) |
||
Misaeです。 理解が浅いので、返事が遅くなってしまいました。 そもそも、以下の型キャスト自体も間違いなのでしょうか? n=(int (*)[MAX])calloc(MAX,sizeof(int)); また、最初に書いた以下の ポインタ変数 n に対しての、 配列の添字 n[i] か ポインタを進める *(n++) でのアクセスは正しいでしょうか? int *n=NULL; int i; n=(int*)calloc(MAX,sizeof(int)); /* 適当な値を代入 */ for(i=0;i<MAX;i++) n[i]=i+10; // 添字による各領域へのアクセス |
No.1633![]() |
Re:動的に確保された複数の領域は配列なのか? 投稿者---YuO(2004/05/04 16:06:06) |
||
>そもそも、以下の型キャスト自体も間違いなのでしょうか? > n=(int (*)[MAX])calloc(MAX,sizeof(int)); nがint (*)[MAX]型でない限り間違いです。 int (*)[MAX]という型は,「『MAX個のint型の要素からなる配列型』へのポインタ型」になります。 この型は,例えば次のように使います。 int array1[MAX]; /* int n; */ int array2[10][MAX]; /* int a[10]; */ int (*p)[MAX]; /* int *p; */ p = &array1; /* p = &n; */ p = array2; /* p = a; */ 原理はコメントに書いたことと一緒です。 つまり,int [MAX]がひとかたまりです。 callocで得るなら, p = calloc(10, sizeof(int [MAX]));のようになります。 ちなみに,配列型へのポインタ型という型は,明示して使うことは滅多にないです。 >また、最初に書いた以下の ポインタ変数 n に対しての、 >配列の添字 n[i] か ポインタを進める *(n++) でのアクセスは正しいでしょうか? nがint *型であり,nが参照するオブジェクトがint [MAX]型の配列の先頭要素である場合, iが範囲[0, MAX)の間においてn[i]というアクセスは可能です。 また,n++という式自体はnが配列要素を参照している場合は有効な式です。 ただし, > n=(int*)calloc(MAX,sizeof(int)); と,nをalias目的に使っているので,n++というiteration目的の操作はすべきではないです。 |