malloc - ライブラリコールの説明 - Linux コマンド集 一覧表
名前
calloc, malloc, free, realloc - 動的なメモリの割り当てと解放を行う
書式
#include <stdlib.h>
void *calloc(size_t nmemb, size_t size);
void *malloc(size_t size);
void free(void *ptr);
void *realloc(void *ptr, size_t size);
説明
calloc ()は size バイトの要素 nmemb 個からなる配列にメモリを割り当て、 割り当てられたメモリに対するポインタを返す。 メモリの内容は数値ゼロ (全ビットがゼロのバイト) にセットされる。
malloc ()は size バイトを割り当て、 割り当てられたメモリに対するポインタを返す。 メモリの内容はクリアされない。
free ()はポインタ ptr が指すメモリ空間を解放する。このポインタは、以前に呼び出された malloc (), calloc (), realloc ()のいずれかが返した値でなければならない。 これ以外のポインタを指定したり、すでに free( ptr ) が実行されていたりした場合の動作は定義されていない。 ptr が NULL の場合には、なんの動作も行われない。
realloc ()は、ポインタ ptr が示すメモリブロックのサイズを変更して size バイトにする。 新旧のサイズのうち、小さいほうのブロックに含まれる内容は変更されない。 新しく割り当てられたメモリの内容は初期化されない。 ptr が NULL の場合には malloc(size) と等価である。 size が 0 の場合には free( ptr ) と等価である。 ptr が NULL 以外の場合、 ptr は以前に呼び出された malloc (), calloc (), realloc ()のいずれかが返した値でなければならない。 ptr が指す領域が移動されていた場合は free( ptr ) が実行される。
返り値
calloc ()と malloc ()の返す値は、割り当てられたメモリへのポインタである。 これはあらゆる種類の変数に対応できるようにアラインメントされている。 割り当て要求に失敗した場合は NULL が返る。
free ()は値を返さない。
realloc ()は新たに割り当てられたメモリへのポインタを返す。 これはあらゆる種類の変数に対応できるようにアラインメントされており、 ptr とは異なることもある。 割り当て要求に失敗した場合は NULL が返る。 size が 0 の場合には、NULL もしくは free ()に渡すことができるポインタが返る。 realloc ()が失敗した場合には、元のブロックは変更されない。 つまり、解放されたり移動されたりはしない。
準拠
C89, C99.
関連項目
注意
Unix98 標準では、 malloc (), calloc (), realloc ()は実行に失敗したときに errno を ENOMEM に設定することになっている。 Glibc ではこれが守られていることを仮定している (またこれらのルーチンの glibc バージョンはこのことを守っている)。 個人的に別の malloc の実装を使っていて、その malloc が errno を設定しない場合には、失敗した際に errno にエラーの理由を設定しないライブラリルーチンがあるかもしれない。
malloc (), free (), realloc ()などにおける事故は、 ほとんどの場合はヒープの破壊 (corruption) が原因である。 例えば、割り当てられた領域をオーバーフローする、 同じポインタに二度 free する、などがこれにあたる。
最近のバージョンの Linux libc (5.4.23 以降) と GNU libc (2.x) では、 malloc の動作を環境変数によって制御できるような実装がされている。 MALLOC_CHECK_ が設定されていると、特殊な実装が用いられ、 単純なエラーには耐えることができるようになる (効率は悪くなる)。例えば、 free ()を同じ引き数で二度呼び出してしまう、 1 バイトだけ行きすぎてしまう (off-by-one バグ) などがこれに当たる。 しかし、これらのエラーの全てを防ぐことができるわけではなく、 その場合にはメモリリークが起こってしまう。 MALLOC_CHECK_ が 0 にセットされていると、ヒープの破壊を黙って無視する。 1 にセットされていると、診断メッセージが標準エラー出力に表示される。 2 にセットされていると、ただちに abort ()が呼び出される。2 に設定しておいて役に立つ状況としては、 実際のプロセスのクラッシュがずっと後に起こり、 本当の原因を探し出すのが非常に困難な場合などが挙げられるだろう。
バグ
デフォルトでは、Linux は楽観的メモリ配置戦略を用いている。
つまり、
malloc
()が NULL でない値を返しても、そのメモリが実際に利用可能であることが
保証されない。これは本当にまずいバグである。
システムがメモリ不足状態になったとき、悪名高いメモリ不足解決器 (OOM killer)
によって一つまたは複数のプロセスが削除される。
突然あるプロセスが削除されるのが望ましくない状況で使用されていて、
しかもカーネルのバージョンが十分に最近のものであれば、このメモリを
割り当て過ぎる動作 (overcommitting behavior) を以下のコマンドで
無効にできる。
# echo 2 > /proc/sys/vm/overcommit_memory
カーネルの付属文書の
vm/overcommit-accounting
と
sysctl/vm.txt
も参照のこと。