MREMAP(2)

名前
mremap - 仮想メモリ・アドレスを再マップする

書式
#include <unistd.h>
#include <sys/mman.h>

void * mremap(void * old_address, size_t old_size , size_t new_size, unsigned long flags);

説明
mremap は存在するメモリ・マップを拡張(または縮小)する。 同時にそれらは移動されるかもしれない(flags 引き数と 可能な仮想(virtual)アドレス空間によって制御される)。 old_address は拡張(または縮小)しようとする仮想メモリ・ブロック の元のアドレス。old_address はページ境界(aligne)に合っていなければ ならないことに注意すること。old_size は元の仮想メモリ・ブロックの サイズ。new_size は要求する変更後の仮想メモリ・ブロックのサイズ。 flags 引き数はフラグのビットマップである。 Linux ではメモリはページに分割される。ユーザー・プロセスは(一つまたは) 複数のリニア(linear)な仮想メモリ・セグメント(segment)を持つ。 それぞれの仮想メモリ・セグメントは(ページ・テーブルに) 一つまたはそれ以上のマップされた実(real)メモリ・ページを持つ。 それぞれの仮想メモリ・セグメントはそれ自身の保護(アクセス権)を持つ、 これはメモリが不正にアクセスされた場合(例えば読み込み専用のセグメントに 書き込んだ場合)、セグメンテーション侵害(segmentation violation)を 引き起こす。 mremap は Linux のページ・テーブル方式を使用する。mremap は 仮想アドレスとメモリ・ページのマップを変更する。これは非常に効率的な realloc を実装するのに使用されている。

フラグ

MREMAP_MAYMOVE
    は現在の仮想アドレスでサイズ変更ができなくて操作を失敗する場合に 仮想アドレスを変更することを指示する。

返り値
成功した場合は mremap は新しい仮想メモリ領域へのポインターを返す。 エラーの場合は -1 が返され、errno が適切に設定される。

エラー

EINVAL
    不正な引き数が与えられた。たいていは old_address がページ境界に 合ってない。

EFAULT
    「セグメンテーション違反(segmentation fault)」、 old_address から old_address+old_size の 範囲のアドレスのどれかがこのプロセスにおいて不正な仮想メモ リ・アドレスである。例え要求したアドレス空間全体のマップが 存在したとしても、それらのマップが異った型ならば EFAULT を 受け取るだろう。

EAGAIN
    メモリ・セグメントがロック(lock)されており、再マップできない。

ENOMEM
    現在の仮想アドレスではメモリ領域が拡張できず、MREMAP_MAYMOVE フラグが flags に設定されていない。または十分な(仮想)メモリが 存在しない。

準拠
このコールは Linux 特有であり、移植を意図したプログラムで使用しては いけない。4.2BSD は (実際に実装されていたわけではないが) 全く異った方式(semantics)による mremap(2) コールを持っている。

関連項目
getpagesize(2), realloc(3), malloc(3), brk(2), sbrk(2), mmap(2)

ページ分割されたメモリに関してのより詳しい説明は あなたの好みの OS の教科書を参照すること (Modern Operating Systems by Andrew S. Tannenbaum, Inside Linux by Randolf Bentson, The Design of the UNIX Operating System by Maurice J. Bach.)