strace
是你的朋友在這裏:
$ strace ./mmap-example mmap-example.c
...
... (lots of output)
...
open("mmap-example.c", O_RDONLY) = 3
fstat(3, {st_mode=S_IFREG|0644, st_size=582, ...}) = 0
mmap(NULL, 582, PROT_READ, MAP_FILE, 3, 0) = -1 EINVAL (Invalid argument)
--- SIGSEGV (Segmentation fault) @ 0 (0) ---
+++ killed by SIGSEGV +++
的mmap
手冊頁告訴你所有你需要知道;)
EINVAL
我們不喜歡addr
,length
,或offset
(例如,他們太 大,或不等在頁面邊界上進行簽名)。
EINVAL
(因爲Linux 2.6.12)length
是0
EINVAL
flags
既不含有MAP_PRIVATE
或MAP_SHARED
,或
包含這兩個值。
-EINVAL
該錯誤是由標記,它們不能爲0要麼MAP_PRIVATE
或MAP_SHARED
具有要被拾取而引起的。我已經能夠在Linux,x86-64上使用MAP_PRIVATE
進行工作。
所以,你只需MAP_PRIVATE添加到mmap()
:
#include <stdio.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <sys/io.h>
#include <sys/mman.h>
int main(int argc, char const *argv[])
{
unsigned char *f;
int size;
struct stat s;
const char * file_name = argv[1];
int fd = open (argv[1], O_RDONLY);
/* Get the size of the file. */
int status = fstat (fd, & s);
size = s.st_size;
f = (char *) mmap (0, size, PROT_READ, MAP_PRIVATE, fd, 0);
for (int i = 0; i < size; i++) {
char c;
c = f[i];
putchar(c);
}
return 0;
}
注:我的第一個答案都包括了EINVAL
另一個可能的原因:
size
必須是整數系統頁面大小的倍數。到 獲取頁面大小使用功能getpagesize()
。
這實際上是不需要,但你必須考慮到,無論哪種方式,映射將始終在系統頁面大小的倍數進行考慮,所以,如果你想計算多少內存實際上是如何通過返回的指針已面市,更新size
因爲這樣:
int pagesize = getpagesize();
size = s.st_size;
size += pagesize-(size%pagesize);
你不檢查open'和'mmap'的'的返回值。如果你這樣做會怎樣? – usr2564301