首页 > 解决方案 > 获取和 mmap 的问题

问题描述

我的老师提供了这段代码,它打开一个文件,使用 mmap 映射到内存中,然后使用 get 写入一个字符串。问题是即使 printf 打印了所有字符串,它也只将字符串的前 2 个字符写入文件。有什么建议吗?

#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;


}

标签: cscanfmmap

解决方案


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

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

如果文件比映射的内存范围短,则在mmap执行时,范围的其余部分为零填充。但是,对该区域的修改不会被写出到后备文件,并且可能对共享映射的其他进程可见也可能不可见,即使MAP_SHARED已设置。

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


推荐阅读