moriya9n.github.io

View My GitHub Profile


kindle 本ベストセラー

みんなのFX

22 July 2018

C言語とポインタ

by moriya9n

C言語のポインタについて書かれた記事は多数あるが、 少し違った視点で書いてみたいと思う。

C言語で作ったプログラムの実行イメージと変数の配置について

変数配置イメージ

ポインタとは、変数やプログラム領域などのメモリ(アドレス)を指すものである。

わかりづらい点

ポインタアクセス

ポインタでの受け渡し

私自身が始めたころわかりづらいと思ったのは、戻り値が return 値ではなく、 引数にポインタとして入っていることがあること。例えば scanf。

int など基本の型で返せない場合や、リターン値が複数ある場合は、リターン値を格納する領域へのポインタを 渡して関数を呼び出し、結果を書き込んでもらう。 例えば、int の値を返してもらう場合は、hoge(&ret) のようにしてポインタを渡す。 サブルーチン側では、

*ret = 123;

などのようにして結果を書き込む。hoge(ret)として、サブルーチン側で

ret = 123;

としても、呼び出し元の値は変わらない。&ret はアドレスでリターンした時アドレスは変わっていなくても、 アドレスの中身を書き換えているから ret の値は変わる。

リターン値

昔はリターン値として構造体を渡せなかった。 例えば構造体を返そうと思い、ローカル変数で構造体を宣言し、そのポインタを 返そうなどということをしようとしてしまう。

しかし、ローカル変数は、関数から戻った時には解放されているので、その構造体のポインタが指す内容には 結果が格納されている保証はない。呼び出し側で構造体を作って、そのポインタを引数で渡す必要があった。

おそらく今でもそのような形式の API コールは多いと思うので、それに倣って、 リターン値にはエラーの有無を返し、結果を格納する構造体へのポインタを渡すのが良いのではないかと思う。

動的な確保

動的にメモリを確保する必要がある場合もあると思う。

その場合は、malloc を使う。しかし、malloc した領域は、free して解放しなければ、確保されっぱなしで、 どんどんメモリを消費することになる。

しばらく動かしているとプログラムが止まってしまうことになるので 解放忘れをしないようにする必要がある。

tags: