我的老师提供了这个代码,它打开一个文件,用mmap映射到内存中,然后使用gets写一个字符串。问题是它只将字符串的前2个字符写入文件,即使printf打印了所有字符串。有什么建议吗?
#include <stdlib.h>
#include <stdio.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <unistd.h>
#define PAGE_SIZE (8192)
int main(int argc, char** argv){
pid_t pid;
int fd;
char* buffer;
if (argc!= 2) {
printf("Syntax: prog file_name\n");
return -1;
}
fd=open(argv[1], O_RDWR);
if (fd== -1) {
printf("open error");
return -2;
}
buffer = (char*)mmap(NULL,PAGE_SIZE,PROT_READ|PROT_WRITE,MAP_SHARED,fd,0);
close(fd);
if (buffer == NULL){
printf("mmap error\n");
return -3;
}
pid = fork();
if(pid == -1){
printf("fork error\n");
return -4;
}
if(pid == 0){
gets(buffer);
return 0;
}
waitpid(pid, NULL);
printf("%s\n",buffer);
return 0;
}
答案 0 :(得分:2)
mmap
在内存区域和文件的当前范围之间创建关联(称为“支持文件”)。它不会改变文件的大小,也不一定考虑文件大小的任何变化。
也许你的老师试图用这个例子向你展示这个事实。
如果文件比映射的内存范围短,则在执行MAP_SHARED
时,扩展区的其余部分将填充为零。但是,对此区域的修改不会写入后备文件,即使已设置ftruncate
,也可能对共享映射的其他进程可见或不可见。
如果已创建启用了写入的映射区域,则应避免引用文件中不存在的区域部分。 (如果您只想将文件作为共享内存的持久备份,则应该使用mmap
将文件大小设置为所需的映射大小。)在调用{{1}}之前必须这样做,因为如果在映射生效时更改了文件的大小,则结果是未定义的行为。