malloc, free, calloc, realloc -
動的なメモリの割り当てと解放を行う
#include <stdlib.h>
void *malloc(size_t size);
void free(void *ptr);
void *calloc(size_t nmemb, size_t size);
void *realloc(void *ptr, size_t size);
malloc() 関数は
size
バイトを割り当て、
割り当てられたメモリに対する
ポインタを返す。
メモリの内容は初期化されない。
size が 0 の場合、
malloc()
は NULL または
free()
に後で渡しても問題の起こらない
一意なポインタ値を返す。
free() 関数はポインタ
ptr
が指すメモリ空間を解放する。このポインタは、
以前に呼び出された
malloc(),
calloc(),
realloc()
のいずれかが返した値で
なければならない。これ以外のポインタを指定したり、すでに
free(ptr) が実行
されていたりした場合の動作は定義されていない。
ptr が NULL
の場合には、何の動作も行われない。
calloc() 関数は
size
バイトの要素
nmemb
個からなる配列にメモリを
割り当て、割り当てられたメモリに対するポインタを返す。
メモリの内容は数値ゼロ
(全ビットが 0 のバイト)
にセットされる。
nmemb
か
size が 0 の場合、
calloc() は NULL または
free()
に後で渡しても問題の起こらない一意な
ポインタ値を返す。
realloc() は、ポインタ
ptr
が示すメモリブロックのサイズを
size バイト
に変更する。領域の先頭から、新旧のサイズの小さい方の位置までの範囲の内容は
変更されない。新しいサイズが前のサイズよりも大きい場合、追加されたメモリは
初期化
されない。
ptr が NULL の場合には
malloc(size) と等価である。
size が 0 で
ptr が NULL
でない場合には、
free(ptr) と等価である。
ptr が NULL 以外の場合、
ptr
は以前に呼び出された
malloc(),
calloc(),
realloc()
のいずれかが返した値でなければならない。
ptr
が指す領域が移動されていた場合は
free(ptr) が実行される。
返り値¶
関数
calloc() と
malloc()
は、割り当てられたメモリへのポインタを返す。
割り当てられたメモリは、あらゆる種類の変数に対応できるようにアラインメントされる。
エラーの場合、これらの関数は
NULL を返す。
size が 0
で呼び出した
malloc()
や、
nmemb か
size が 0
で呼び出した
calloc()
が成功した場合にも NULL
が返される。
free()
関数は値を返さない。
realloc()
関数は新たに割り当てられたメモリへのポインタを返す。
これはあらゆる種類の変数に対応できるようにアラインメントされており、
ptr
とは異なることもある。割り当て要求に失敗した場合は
NULL が返る。
size が 0
の場合には、NULL
もしくは
free()
に渡すことができるポインタが返る。
realloc()
が失敗した場合には、元のブロックは変更されない。
つまり、解放されたり移動されたりはしない。
C89, C99.
デフォルトでは、Linux
は楽観的メモリ配置戦略を用いている。つまり、
malloc() が NULL
でない値を返しても、そのメモリが実際に利用可能であること
が保証されない。システムがメモリ不足状態になったとき、メモリ不足解決器
(OOM killer)
によって一つまたは複数のプロセスが削除される。
詳しい情報は、
proc(5)
の
/proc/sys/vm/overcommit_memory と
proc/sys/vm/oom_adj、およびカーネルのソースファイルの
Documentation/vm/overcommit-accounting
を参照のこと。
通常、
malloc()
は、ヒープからメモリを割り当て、必要に応じてヒープのサイズを
sbrk(2)
を使って調節する。
MMAP_THRESHOLD
バイトよりも大きなメモリブロックを割り当てる場合、
glibc の
malloc() 実装は
mmap(2)
を使ってプライベートな無名マッピング
(anonymous mapping) として
メモリを割り当てる。
デフォルトでは
MMAP_THRESHOLD
は 128 kB だが、
mallopt(3)
を使って調整できる。
mmap(2)
を使って行われたメモリ割り当ては
RLIMIT_DATA
リソース上限の影響を受けない
(
getrlimit(2) 参照)。
マルチスレッドアプリケーションでのデータ破損を回避するため、内部では
mutexを
使用して、これらの関数で利用されるメモリ管理用のデータ構造を保護している。
複数のスレッドが同時にメモリの確保や解放を行うようなマルチスレッドアプリケー
ションでは、これらの
mutex
の衝突が起こり得る。マルチスレッドアプリケーション
でのメモリ割り当て処理にスケーラビリティを持たせるために、glibc
では mutex の
衝突が検出された際には追加の
メモリ割り当て領域
を作成する。
追加領域の各々は、(
brk(2) や
mmap(2) を使って)
システムにより内部的に
割り当てられた大きな領域で、それぞれ独自の
mutex
により管理されている。
UNIX 98 標準では、
malloc(),
calloc(),
realloc()
は実行に失敗したときに
errno を
ENOMEM
に設定することになっている。
Glibc
ではこれが守られていることを仮定している
(またこれらのルーチンの
glibc
バージョンはこのことを守っている)。
個人的に別の malloc
の実装を使っていて、その
malloc が
errno
を設定しない場合には、失敗した際に
errno
にエラーの理由を設定しないライブラリルーチンがあるかもしれない。
malloc(),
calloc(),
realloc(),
free()
における事故は、
ほとんどの場合はヒープの破壊
(corruption) が原因である。
例えば、割り当てられた領域をオーバーフローする、
同じポインタに二度 free
する、などがこれにあたる。
Linux libc
の新しいバージョン
(5.4.23 より後) と glibc (2.x)
には、
環境変数で動作を調整できる
malloc()
実装が含まれている。
詳細は
mallopt(3)
を参照のこと。
関連項目¶
brk(2),
mmap(2),
alloca(3),
malloc_get_state(3),
malloc_info(3),
malloc_trim(3),
malloc_usable_size(3),
mallopt(3),
mcheck(3),
mtrace(3),
posix_memalign(3)
この文書について¶
この man ページは Linux
man-pages
プロジェクトのリリース
3.41 の一部
である。プロジェクトの説明とバグ報告に関する情報は
http://www.kernel.org/doc/man-pages/
に書かれている。