メモリマッピング(mmap / munmap)
ファイルをメモリの一部として直接読み書きする mmap の考え方。read/write を繰り返さずポインタでアクセスできる仕組みと、ページ境界という制約を確認する。
ファイルの中身を読むとき、普通は open して read でバッファへ運ぶ。だが「ファイルをそのままメモリ上に広げて、配列のように直接触れたら楽なのに」と思う場面がある。それを叶えるのが mmap だ。
🧩 ファイルをメモリに貼り付ける
mmap はファイルの一部(または全部)をプロセスのアドレス空間に対応づける。対応づけが済むと、返ってきたポインタを使ってメモリを読むだけでファイルの中身が読め、read を繰り返す必要がなくなる。使い終わったら munmap で対応づけを外す。
💡
ポイントEX: 書式は `void *mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset);`。`prot` に PROT_READ / PROT_WRITE でアクセス権を、`flags` に MAP_SHARED / MAP_PRIVATE で共有か複製かを指定する。`fd` は open で得たディスクリプタ。
💡
ポイントTIP: 戻り値がエラーのときは NULL ではなく `(void *)-1`(MAP_FAILED)が返る。`if (p == MAP_FAILED)` で判定する点が、多くのシステムコールの「-1でエラー」と少し違うので注意する。
🧩 ページ単位という制約
メモリの割り当てはページという固定サイズの単位で行われる。mmap の offset もこのページサイズの倍数でなければならない。ページサイズは環境で決まっていて、コマンドで確認できる。
💡
ポイントEX: `getconf PAGESIZE` と打つと、その環境のページサイズ(多くの環境で 4096 バイト)が表示される。mmap の offset はこの値の倍数に揃える。
💡
ポイントANALOGY: read/write が「本を1ページずつ手で書き写す」なら、mmap は「本の該当ページを机に直接広げて、そのまま指でなぞる」イメージ。写す手間が消える代わりに、机(アドレス空間)に広げる下準備が要る。
画像ファイルのヘッダだけを覗いて幅や高さを知りたい、といった「ファイルの特定位置をランダムに触りたい」用途で mmap は特に便利だ。lseek で位置を動かしながら読むより、貼り付けたメモリを普通のポインタ演算で辿るほうが素直に書ける。
この項目に出てくる用語
mmapえむまっぷ
ファイルやデバイスをメモリ空間に対応づけるシステムコール。
ページぺーじ
メモリ管理の固定サイズ単位。