BRK(2)

名称
brk, sbrk - データセグメントのサイズを変更する

ライブラリ
libc

書式
<sys/types.h> <unistd.h> int brk(const void *addr) void * sbrk(intptr_t incr)

解説
brk() 関数と sbrk() 関数は、現代的な仮想メモリ管理が現れる以前の、古いインタフェースです。

brk() 関数と sbrk() 関数は、プロセスのデータセグメントに割り当てられた メモリ量を変更するために使用されます。 これは、 “ブレーク” 位置を移動することで実現します。 ブレークとは、プロセスの初期化されていないデータ ( “BSS” としても知られています) の後の最初のアドレスのことです。

brk() 関数は、ブレークを addr に設定します。

sbrk() 関数は、ブレークを incr バイトだけ増し、結果として少なくとも incr バイトの新規メモリをデータセグメントに割り当てます。 incr が負の場合、ブレークは incr バイトだけ減らされます。

注
カーネルが管理する実際のプロセスデータセグメントサイズは ページ単位でのみ増減しますが、 これらの関数は、ブレークを境界にあわない値に設定することを許します (すなわち、データセグメントの最終ページ中の任意のアドレスを指して構いません)。

プログラムのブレークの現在値は、 sbrk(0) を呼び出すことで判定可能です。 end(3) も参照してください。

getrlimit(2) システムコールは、 データ セグメントの許容できる最大のサイズを決定するのに利用できます。 “etext + rlim.rlim_max” を越えるブレークを設定することはできません。 rlim.rlim_max は getrlimit(RLIMIT_DATA, &rlim) の呼び出しから返された値です (etext の定義については end(3) を参照してください)。

戻り値

sbrk() 関数は、成功すると古いブレーク値を返します。 失敗すると、値 (void *)-1 が返し、グローバル変数 errno にエラーを表す値を設定します。

エラー
brk() および sbrk() 関数は、次の場合に処理に失敗します:

[EINVAL]
    要求されたブレーク値がデータセグメントの先頭を越えています。

[ENOMEM]
    setrlimit(2) が設定したデータセグメントサイズの限界を越えています。

[ENOMEM]
    データセグメントの拡張に必要なスワップ領域内の空間が不充分です。

関連項目
execve(2), getrlimit(2), mmap(2), end(3), free(3), malloc(3)

バグ
brk() または sbrk() と、 malloc(3), free(3) やこれに類する関数を混在させると、移植性のないプログラム動作となります。

ブレークの設定は、スワップ空間の一時的な不足のために処理が失敗する 可能性があります。 これは getrlimit(2) を使用しないと、データセグメントの最大サイズを越えたことに起因する 失敗と区別することはできません。

歴史
brk() 関数は AT&T UNIX で登場しました。