2017-12-02 15 views
0

。私はここに+ 10をマッピングしなぜファイルにmmapできますが、ファイルサイズを超えることはできますか?例えば、

fd = ::open ("/test.txt", O_RDONLY, 0); 
struct stat buf; 
fstat(fd, &buf); 
char* addr = (char*)::mmap(NULL, buf.st_size + 10, PROT_READ, MAP_PRIVATE | MAP_POPULATE, fd, 0); 

注意してください。 それでも動作しますか?

なぜシステムにチェックが適用されないのですか? 危険ですか? MMAPの

おかげ

+0

タグを編集します。 'c'と' C++'の両方が誤解を招く – coderredoc

+0

なぜそれが必要ですか? – Stargateur

+0

@coderredoc mmap()は、cとC++の両方から同じように呼び出すことができます。 –

答えて

2

シグネチャは次のとおりです。

void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset); 

マイケル・ケリスクを引用すると:

長さ引数はバイト単位でマッピングのサイズを指定します。 長さは、システム・ページ・サイズ (はsysconf(_SC_PAGESIZE)によって返される)の倍数である必要はありませんが、カーネルがこのサイズの 単位でマッピングを作成し、その結果、長さは、実質的に、に切り上げられ ページサイズの次の倍数。 - Linuxのプログラミング・インタフェース(第49章)

ロバート愛を引用する:

のmmap()システムコールは、ページ上で動作します。 addrパラメータとoffsetパラメータは、ページ・サイズの境界に整列させる必要があります。つまり、ページサイズの整数倍でなければなりません。したがって、マッピングはページの整数倍です。呼び出し元によって提供されたlenパラメータが、ページの境界に配置されていない場合(おそらく、基礎となるファイルのサイズがページサイズの倍数ではないため)、マッピングは次の全ページに切り上げられます。最後に有効なバイトとマッピングの終わりの間に、この追加されたメモリ内のバイトはゼロで埋められます。その領域からの読み込みはゼロを返します。そのメモリーへの書き込みは、たとえMAP_SHAREDとしてマップされていても、バッキング・ファイルに影響しません。元のlenバイトだけがファイルに書き戻されます。 - Linuxシステムプログラミング(第4章)

+0

これは、mmapメモリが常に要求より大きい場合があることを示しています。しかし、OPの質問はむしろmmapメモリがファイルをバックアップするファイルよりも厳密に大きい場合、例えばファイルサイズを超えるメモリアクセスがフォールトを発生させるような場合にどうなるのでしょうか?黙ってファイルをゼロで拡張しますか?等 –

+0

こんにちはハーゲン、 編集された答えをご覧ください。 – nachiketkulk

1

あなたのシステムはLinuxを実行していると仮定します。 intro(2)を必ず読んでください。

私たちは、そのサイズ以上mmap(2)ファイルができ、我々がなかった場合は、ページサイズの倍数のファイルのみが(一般的に4Kバイト、おそらく1Mバイト、PAGESIZEsysconf(3)を参照)、メモリがマップされる可能性があるため。そうであれば、メモリマップされたファイルはずっと役に立たないでしょう。また、mmap -edファイルのサイズは、時間とともに変化することができます(他のプロセスwrite(2)は-ingと、それに追加するなど、ftruncate(2)に呼び出して...)ので、それはkernelが必要(または強制)するためにも意味がありませんということ変更されません。

は慎重 mmap(2)のドキュメントを読んで、それは言う:

ファイルはページサイズの倍数にマッピングされています。 のページサイズの倍数ではないファイルの場合、 がマップされている場合、残りのメモリはゼロになり、その領域への書き込みはファイルに書き出されません。

(あなたが想像するものよりもはるかに多く、おそらく、カーネルはいくつかのチェックを行っているコースのように)

mmapあなたのコードはそれを確認する必要がありますので、例えば、失敗する可能性がありますでそれに従うことによって:

if ((void*)addr == MAP_FAILED) 
     { perror("mmap"); exit(EXIT_FAILURE); }; 

ところで、あなたの質問には、C++特有の問題ではありませんが、POSIXやLinuxの特定の(他のオペレーティングシステムがmemory mapped filesを提供していない可能性がある、またはそれらに他の制約を置くことができる)です。

メモリマッピングは非常に一般的です。これはmmapによって使用され、またexecve(2)時に使用されます。 ()をusing/proc/proc(5)を参照し、端末にcat /proc/self/mapscat /proc/$$/mapsを試してください)を理解できます。 mmapが頻繁に使用されます。malloc(3)operator newdlopen(3)ld-linux(8)の動的リンク共有ライブラリです。

LinuxまたはPOSIXプログラミングに関する書籍(例:Advanced Linux Programming、無料でダウンロード可能なもの、またはそれより新しいもの)とOperating Systems: Three Easy Piecesも参照してください。

関連する問題