Search on the blog

2011年2月5日土曜日

ポインタの参照渡し

今日は、ポインタとアドレスの違いについて。

まず、両者の違いについて。
ポインタ(以下では、アドレスとの違いを明確にするため”ポインタ変数”と呼ぶ)はあくまでも、アドレスを指し示す入れ物である。
ポインタ変数自体はアドレスではなく、intやcharと同じ変数である。
これに対してアドレスは、固定番地である。メモリの物理的な位置である。

ちょっと突っ込んで考えると、ポインタ変数にもアドレスが存在するし(アドレスを指し示す変数のアドレスというイメージ)。
よってポインタ変数を関数に参照渡ししたい場合は、ポインタ変数のアドレスを渡す必要がある。

具体的な例を見てみよう。
main()でchar型のポインタ変数を宣言し、setStr()という関数にポインタ変数を渡して、文字列を取得する。
まずは、ダメな例から。

void setStr(char *a) {
a = new char [8];
strcpy(a, "Hello");
}

int main() {
char *a = NULL;

setStr(a);
cout << a << endl;
return 0;
}
上の書き方では、setStr()を抜けた後もaはNULLのままです。
setStr()に渡したのは、ポインタ変数です。
setStr()では、仮引数aのコピーを作り、関数内だけで有効なaに対して処理をします。よって、setStr()をreturnするときには、aに対する変更はmainに反映されません。

次に、良い例。
下の書き方では、ポインタ変数のアドレスを渡しています。

void setStr(char **a) {
*a = new char [8];
strcpy(*a, "Hello");
}

int main() {
char *a = NULL;

setStr(&a);
cout << a << endl;
return 0;
}
これだと、期待した結果が得られます。
くどいようですが、動的メモリの確保をする場合は「ポインタ変数とアドレスは異なるものだ」としっかり理解しておくことが大切です。

0 件のコメント:

コメントを投稿