mmap在标准C99(或C11)规范中不存在。它在POSIX中定义。
所以假设你有一个POSIX系统(例如Linux)的,您可以先open(2)文件进行读&写:
int myfd = open("hello.txt", O_RDWR);
if (myfd<0) { perror("hello.txt open"); exit(EXIT_FAILURE); };
然后你得到的文件大小(和其他元数据) fstat(2):
struct stat mystat = {};
if (fstat(myfd,&mystat)) { perror("fstat"); exit(EXIT_FAILURE); };
现在文件的大小是mystat.st_size。
off_t myfsz = mystat.st_size;
void*ad = mmap(NULL, myfsz, PROT_READ|PROT_WRITE, MAP_SHARED,
myfd, 0);
if (ad == MMAP_FAILED) { perror("mmap"); exit(EXIT_FAILURE); };
然后,我们可以覆盖的第一个字节(和我们检查确实该文件中的第一个字节是H,因为您承诺如此):
assert (*(char*ad) == 'H');
((char*)ad) = 'R';
我们可能会调用msync(2)来确保文件现在在磁盘上更新。如果我们不这样做,它可能会在稍后更新。
值得注意的是非常大的映射(尤其是那些比可用RAM大很多),我们可以帮助内核(及其page cache)与通madvise(2)或posix_madvise(3)给出提示...
注意的映射仍然有效即使在close(2)之后。使用munmap & mprotect或mmap与MAP_FIXED在相同的地址范围内更改它们。
在Linux上,您可以使用proc(5)来查询地址空间。因此,您的程序可以读取(例如,在fopen之后,在循环中使用fgets)伪/proc/self/maps文件(或/proc/1234/maps用于pid 1234的处理)。
BTW,mmap被dlopen(3)使用;它可以被称为很多次,我的manydl.c程序表明,在Linux上,您可以拥有成千上万的共享文件(数十万个内存映射)。