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( )
を渡します。要約すると,x
,f( )
,y
がポインタであり,x
→ f( )
→ y
という連携がすべて同じ型のポインタ間になっています。
malloc
によって割り当てたメモリ領域は,解放するまでメモリは消費されています。例えば,上の場合で main
関数における printf
の実行後にメモリが不必要になるのであれば,
free(y);
とすれば,malloc
で割り当てたメモリ領域は解放されます。割り当ての場合,変数の寿命は割り当ててから解放するまでの期間となります。
メモリ・リーク(Memory Leak)
プログラムが常に動作しているような場合,malloc
で割り当てたメモリ領域を free
で適切に解放しないと,メモリ消費が増えてゆく「メモリリーク」が起こる。メモリリークが起こり,メモリを消費尽くすと,システムがダウンする。