<ポインタへのポインタ>
ポインタへのポインタを使うと、自由度の高い二次元データの取り扱いができます。
(例)
#include
<stdio.h>
int
main(void) {
int
**plist; /*
ポインタへのポインタplistを宣言 */
int
i, n, narrays;
printf("Input
number of arrays :"); /* データ配列の数narraysを入力 */
scanf("%d",
&narrays);
plist
= (int **)malloc(sizeof(int *) * narrays); /*
narrays個のint型ポインタのためのメモリー領域を確保 */
for
(i = 0; i < narrays; i++) {
printf("
Input number of elements for array #%d : ", i+1); /* i番目のデータ配列の大きさnを指定 */
scanf("%d",
&n);
/*
n個のint型変数のためのメモリー領域を確保し、そのアドレスをポインタ配列plistのi番目の要素として格納 */
plist[i]=(int
*)malloc(n * sizeof(int));
}
for
(i = 0; i < narrays; i++) /*
各データ配列の先頭アドレスを表示 */
printf("address
of array #%d: %p\n", i+1, plist[i]);
for
(i = 0; i < narrays; i++) /*
各データ配列のメモリを解放 */
free(plist[i]);
free(plist); /*
ポインタ配列plistのメモリを解放 */
return
0;
}
この例では、まずこれから作成するデータ配列の数(narrays)を入力し、次にそれぞれのデータ配列の要素数(n)を指定して動的にメモリ領域を確保しています。mallocに失敗した時のエラー処理は省いています。
手順としては、まずポインタへのポインタを宣言します。
int
**plist;
これに、narray個のポインタを格納するための領域を確保します。一つのint型ポインタ変数を格納するために必要なメモリサイズはsizeof(int *)で得られます。
plist
= (int **)malloc(sizeof(int *) * narrays);
次に、順次指定された要素数のデータ配列のためのメモリ領域をmallocで確保し、それへのポインタをplistの各要素に格納します。
for
(i = 0; i < narrays; i++) {
...
scanf("%d",
&n);
plist[i]=(int
*)malloc(n * sizeof(int));
}
これでデータ領域の確保は完了です。
使い終わったら、まず各データ配列をそれぞれ解放します。
for
(i = 0; i < narrays; i++)
free(plist[i]);
最後にポインタのリストの領域を開放して終わりです。
free(plist);
出力は、確保した配列のアドレスです。たとえば以下のようになります。
(実行例)
Input
number of arrays :5<enter>
Input number of elements for array #1 :
4<enter>
Input number of elements for array #2 :
16<enter>
Input number of elements for array #3 :
64<enter>
Input number of elements for array #4 :
256<enter>
Input number of elements for array #5 :
1024<enter>
address
of array #1: 0x500160
address
of array #2: 0x500170
address
of array #3: 0x5001b0
address
of array #4: 0x2800400
address
of array #5: 0x2800800
この処理系では、mallocで確保されるメモリ領域は、サイズによって異なるアドレス域に置かれるようです。