<ポインタを返す関数>
ライブラリ関数の中で、新たに動的にメモリ領域を確保するような関数は、確保した領域を指すポインタを返却値として返します。もちろん、malloc関数自体がその典型例です。
malloc関数だけでなく、ファイル入出力の時に使うfopen関数も、内部でFILE構造体のためのメモリーを確保し、それへのポインタを返します。いずれも場合も、何らかの原因で失敗した場合(メモリ不足、指定したファイルがない、など)は、NULLポインタを返します。呼び出し側で返値をチェックすることで、エラー処理ができるようにするためです。
メモリ領域の確保を伴うユーザー関数を作る時にも、何か問題があったらNULLを返すようにしておくとよいでしょう。
<関数内で確保したメモリの解放>
(例)
int
main(void) {
int
*ip;
...
ip
= int_malloc(1000); /*
関数int_mallocを呼び出し、int型変数1000個分のメモリを確保 */
...
free(ip); /*
int_mallocで確保したメモリ領域を開放 */
...
}
int
*int_malloc(long n) {
int
*ptr;
ptr
= (int *)malloc(n*sizeof(int)); /*
int型変数n個分のメモリを確保し、そのアドレスをptrに代入 */
return
ptr; /*
ptrの値(確保したメモリ領域のアドレスを返す */
}
この例でのint_malloc関数は、引数で指定された要素数のint型配列のためのメモリを確保します。int_mallocの中でmallocを呼び出し、確保したメモリを指すポインタをptrに受けて、それをmainに返却しているだけです。もし確保に失敗しても、mallocがNULLを返してくるのをそのままreturnするだけです。
もしかしたら、「int_malloc内でmallocでメモリを確保したのにfreeで解放しなくていいのか」、と疑問に思うかもしれません。実際にはfreeは呼び出し元で行います。int_malloc内で確保されたメモリのアドレスは、ptrを経て、呼び出し元のipにコピーされているので、そこでfree(ip)とやれば、きちんと解放されます。逆にint_malloc内でfree(ptr)としてしまったら、せっかく確保したメモリを、呼び出し元で使う前に解放してしまうことになります。