ポインタへのポインタ

ポインタは、変数のアドレスを持つ変数・・・。
ということは、そのポインタへのポインタを定義することも可能・・・。

int **pp;

このように宣言すれば、ppはint型変数へのポインタを格納するポインタになる・・・。
これを使った2つの例を示す・・・。

まず、動的な二次元配列の場合・・・。

int **型(int型ポインタへのポインタ)ptr_to_ptrを宣言・・・。

int *型(int型ポインタ)動的配列を要素数5個分mallocで用意、戻り値はint **型になるのでptr_to_ptrで受け取る・・・。

ptr_to_ptrの参照先である*ptr_to_ptrは、int *型動的配列の0番目の要素なので、int型動的配列をmallocで要素数5個分確保し、そのポインタをここに格納・・・。
それをint *型動的配列の4番目まで繰り返していく・・・。

このように、動的に二次元配列を作る場合、全体の先頭はポインタへのポインタとなる・・・。

各要素に値をセット・・・。
5 * i + jとすれば、0から24まで順に入っていく・・・。

*(*(ptr_to_ptr + i) + j)とすれば、それぞれの値を参照できる・・・。

解放するときは、*(ptr_to_ptr + i)でint *型ポインタを1つずつ解放し、最後にint **型ポインタのptr_to_ptrを解放・・・。

さて、もう一つの例は、関数の引数として配列バッファを指す予定のポインタ変数を渡す場合・・・。

動的配列を作成してくれるcreateと破棄してくれるdestroyの引数はchar **型(char型ポインタへのポインタ)である・・・。

char *型(char型動的配列へのポインタ)のbuf_ptrはNULLにしておいていい・・・。

createに&buf_ptr(buf_ptrのアドレス)を渡す・・・。
buf_ptrはchar *型なので、&buf_ptrならchar **型だ・・・。

ptrの参照、*ptrはchar動的配列へのポインタなので、mallocで動的配列を確保しその戻り値を格納・・・。
strcpyで"ABCDE"をセット・・・。

main関数からbuf_ptrを出力・・・。

出力したら、buf_ptrをdestroyで破棄・・・。
createと同じように&buf_ptrで渡す・・・。


ptrを破棄・・・。

で*ptrにはNULLをセットしておく・・・。

このように動的配列を内部でいじってほしい場合は、ポインタへのポインタになることがある・・・。
今回のcreate/destroyは配列の確保と文字列のセットと解放だけだが、それ以外にもいろいろと動的配列をいじるような場合もあるだろう・・・。

$ vi pointer_to_pointer.c
$ gcc pointer_to_pointer.c -o pointer_to_pointer
$ ./pointer_to_pointer
*(*(ptr_to_ptr + 0) + 0) = 0
*(*(ptr_to_ptr + 0) + 1) = 1
*(*(ptr_to_ptr + 0) + 2) = 2
*(*(ptr_to_ptr + 0) + 3) = 3
*(*(ptr_to_ptr + 0) + 4) = 4
*(*(ptr_to_ptr + 1) + 0) = 5
*(*(ptr_to_ptr + 1) + 1) = 6
*(*(ptr_to_ptr + 1) + 2) = 7
*(*(ptr_to_ptr + 1) + 3) = 8
*(*(ptr_to_ptr + 1) + 4) = 9
*(*(ptr_to_ptr + 2) + 0) = 10
*(*(ptr_to_ptr + 2) + 1) = 11
*(*(ptr_to_ptr + 2) + 2) = 12
*(*(ptr_to_ptr + 2) + 3) = 13
*(*(ptr_to_ptr + 2) + 4) = 14
*(*(ptr_to_ptr + 3) + 0) = 15
*(*(ptr_to_ptr + 3) + 1) = 16
*(*(ptr_to_ptr + 3) + 2) = 17
*(*(ptr_to_ptr + 3) + 3) = 18
*(*(ptr_to_ptr + 3) + 4) = 19
*(*(ptr_to_ptr + 4) + 0) = 20
*(*(ptr_to_ptr + 4) + 1) = 21
*(*(ptr_to_ptr + 4) + 2) = 22
*(*(ptr_to_ptr + 4) + 3) = 23
*(*(ptr_to_ptr + 4) + 4) = 24
buf_ptr = ABCDE
$

実行するとこんな風に出力される・・・。

Sample/pointer_to_pointer.c at master · bg1bgst333/Sample · GitHub