ゆずめも

メモ的なブログです。主に勉強した事について書いてます。

C言語の多重間接参照について

注意

書いてる本人は理解してません
学んだことをまとめる記事なので間違った情報が記載されている可能性があります

ご利用は計画的にです。

C言語勉強してます

最近C言語を勉強してて
多重間接参照が全然ピンと来なかったので言語化しようと書いてます

多重間接参照とは

多重間接参照(multiple indirection)は「ポインタのポインタ」らしい

多重間接参照 - wikipedia

ポインタのポインタって

これを調べてると、こんな感じのサンプルコードがよく出てくる(includeとか省略)

int *p;
int **pp;
int ary[] = {1,2,3,4,5};

p = ary;
pp = &p;

printf("%d", **pp); //=> 1が表示される

これがポインタのポインタです!(どやぁ
というのが多く見られるんですが、このコードにはなんの意味もない気が・・・

どういう時に使うのか

上のサンプルからじゃ何も察せない人種なので
実例というか使用例

データを関数の外へ出すのに使う

Google先生に聞いてみたところ 関数内で作られたデータを外へ出すのに使うらしい

とりあえずサンプルで関数内でint dを定義して
そのint dの値100main関数で表示したいと思います

まずは成功パターン

#include <stdio.h>

void test(int**);

int main() {
  int *p = NULL;
  test(&p);
  printf("%d\n", *p);//=>100
}

void test(int **pp) {
  int d = 100;
  *pp = &d;
}

これをこう書くと動かなくなる
(ポインタのポインタじゃない版)

#include <stdio.h>

void test(int*);

int main() {
  int *p = NULL;
  test(p);
  printf("%d\n", *p);//=>error: segmentation fault
}

void test(int *pp) {
  int d = 100;
  pp = &d;
}

なぜ動かないのか

成功パターンの場合

test関数にpを渡すときにアドレスを渡しているので
pppのアドレスhogeが入ってポインタのポインタとして
pfugaのアドレスが入り100を参照できる

f:id:yuzu441:20160422160923p:plain

失敗したパターン

pの中は定義してから何も入れてないので空

test関数へ渡す時にアドレスではなく中のアドレス値(空だけど)を
渡しているので、ppからうまくpに値を渡せずうまくいかない

f:id:yuzu441:20160422161217p:plain

まとめ

何故か研修で使ってるPCでgdbが動かなくて辛い・・・
でも調べた感じ的にはあんまり間違ってないと思う