ベスパリブ

プログラミングを主とした日記・備忘録です。ベスパ持ってないです。

ポインタの値渡しを理解する(あるいはポインタのポインタの使い所)

以下のようなコードがあったわけです。

#include <stdio.h>
char data[16] = "abcdefg";

int main(void){
    // Your code here!
    char* pData = NULL;
    
    pData = data;

    printf("%s\n", pData); // abcdefg
}

以下のように関数にしたかったわけです。

#include <stdio.h>
char data[16] = "abcdefg";

void func(char* pData){
    pData = data;
}

int main(void){
    // Your code here!
    char* pData = NULL;
    
    func(pData);

    printf("%s\n", pData);  // Runtime error(Exit status:139(Invalid memory reference))
}

エラーが出るわけです。
それぞれのアドレスを表示してみます。

#include <stdio.h>
char data[16] = "abcdefg";

void func(char *pData){
    pData = data;
    printf("func-in: %d\n", pData);  // func-in: 6295616
}

int main(void){
    // Your code here!
    char* pData = NULL;
    
    func(pData);
    printf("func-out: %d\n", pData);  // func-out: 0
    
    pData = data;
    printf("%d\n", pData);  // 6295616
    
}

これなんでだろ~ってずっと悩んでいたんですが、小一時間悩んで、このfunc()に渡しているpDataはいわゆる「ポインタの値渡し」というやつでは?と思い至る。
その場合、ポインタのポインタを渡せば解決できるかもと思い修正。func2()を作成します。

#include <stdio.h>
char data[16] = "abcdefg";

void func(char *pData){
    pData = data;
    printf("func-in: %d\n", pData);  // func-in: 6295616
}

void func2(char **pData){
    *pData = data;
    printf("func2-in: %d\n", *pData);  // func2-in: 6295616
}

int main(void){
    // Your code here!
    char* pData = NULL;
    
    func(pData);
    printf("func-out: %d\n", pData);  // func-out: 0
    
    func2(&pData);
    printf("func2-out: %d\n", pData);  // func2-out: 6295616
    printf("%s\n", pData);  // abcdefg
    
    pData = data;
    printf("%d\n", pData);  // 6295616
    
}

オッ、意図したとおりに動作しました。
C言語に参照なし」とは言いますが、こうして見ると、「&」が参照渡しの記号に見えてしょうがない。