gets和mmap的问题

时间:2018-06-08 15:16:00

标签: c scanf mmap

我的老师提供了这个代码,它打开一个文件,用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;


}

1 个答案:

答案 0 :(得分:2)

mmap在内存区域和文件的当前范围之间创建关联(称为“支持文件”)。它不会改变文件的大小,也不一定考虑文件大小的任何变化。

也许你的老师试图用这个例子向你展示这个事实。

如果文件比映射的内存范围短,则在执行MAP_SHARED时,扩展区的其余部分将填充为零。但是,对此区域的修改不会写入后备文件,即使已设置ftruncate,也可能对共享映射的其他进程可见或不可见。

如果已创建启用了写入的映射区域,则应避免引用文件中不存在的区域部分。 (如果您只想将文件作为共享内存的持久备份,则应该使用mmap将文件大小设置为所需的映射大小。)在调用{{1}}之前必须这样做,因为如果在映射生效时更改了文件的大小,则结果是未定义的行为。