法大奥山研究室

 previous  contents

10.12. ポインタを返す関数 char *f()


 今度は逆に,アドレスを返す関数,「ポインタ関数」を作成してみましょう。

/* Example 10.17 */

#include <string.h>
#include <stdlib.h>
#include <stdio.h>

char *f(void);

int main(void)
{
       char *y;

       y = f();
       printf("(2) %s [%p]\n", y, y);

       exit(0);
}

char *f(void)
{
       char str[8] = "testing";
       char *x;

       x = malloc(strlen(str) + 1);
       if(x == NULL) { exit(1); }

       strncpy(x, str, strlen(str));
       printf("(1) %s [%p]\n", x, x);

       return x;
}

ソース内の malloc は,ライブラリ stdlib.h で定義されている関数で,引数に指定したバイト数分のメモリを割り当て,そのポインタを返します。メモリの割り当てに失敗した場合には,NULLポインタを返します。(man 3 malloc で確認して下さい。)実行結果は次の通りです。

(1) testing [0x442b0]
(2) testing [0x442b0]

角括弧内はアドレスです。関数 f 内のポインタ x が指しているアドレス(出力 1)と main関数内のポインタ y が指しているアドレス(出力 2)が同じであることが確認できます。関数 f がアドレスを返している様子が分かるかと思います。

 アドレスを返すためのポイントは,f( ) 自体がポインタとなるよう,ポインタ宣言 (char *f) していること,そして,それが返す変数もポインタ宣言(char *x)していることです。(返却値型 char *return で返す型 char * を一致させるようにしましょう。f( ) 自体がポインタなのですから,return には返却値型と同じ型のポインタを指定します。)そして,main 関数で受け取る y もポインタであり,それにポインタ f( ) を渡します。要約すると,xf( )y がポインタであり,xf( )y という連携がすべて同じ型のポインタ間になっています。

 malloc によって割り当てたメモリ領域は,解放するまでメモリは消費されています。例えば,上の場合で main関数における printf の実行後にメモリが不必要になるのであれば,

free(y);

とすれば,malloc で割り当てたメモリ領域は解放されます。割り当ての場合,変数の寿命は割り当ててから解放するまでの期間となります。

Q メモリ・リーク(Memory Leak)
 プログラムが常に動作しているような場合,malloc で割り当てたメモリ領域を free で適切に解放しないと,メモリ消費が増えてゆく「メモリリーク」が起こる。メモリリークが起こり,メモリを消費尽くすと,システムがダウンする。


 previous  contents