【发布时间】:2023-03-08 00:44:02
【问题描述】:
在 C++ 中,在 Linux 上,当我使用 open() 打开一个文件,然后使用 mmap() 对其进行内存映射后,我会得到一个 void*,我可以将其类型转换为例如char* 并根据需要读取。
但是,假设我想使用 std::vector 来访问该数据。我怎样才能做到这一点?
起初我以为我可以为我的 std::vector 制作一个自定义分配器。但我看到了两个问题:
- 它的
allocate()方法将只接收一个大小参数。这还不够,因为它还需要知道已经映射的地址,而不是分配一个新地址(分配器通常会这样做)。 - 它的
deallocate()方法——要正确地做到这一点——需要取消映射缓冲区(很简单,一旦解决了上面的#1)和close()文件描述符(很难,因为它没有办法知道这个值。)
我考虑过可能将这个元数据(现有的映射地址和文件描述符)存储在我的自定义分配器引用的已知位置,但如果不使 TLS 复杂化,这将不是线程安全的。
以上方法有可能吗?还是不明智(如果是,请解释)?是否有其他标准库类可以满足我的目的?
我想要这样做的原因是为了避免在解释该内存映射区域中的二进制数据的类中使用原始/POD 指针。
【问题讨论】:
-
新的
class怎么样?构造函数获取文件名并执行open和mmap,析构函数munmap和close。然后添加您需要的方法,例如operator[]、begin()和end()。 -
@mch 我也在想同样的事情。我制作了this
Mmapclass,它可以变成template,以迭代非constT*s。只要Ts 是微不足道的,它应该可以工作。 -
这只是把罐子踢到了路上。而不是在我现有的类中使用原始指针,现在我将它放在新类中。 .... 至少对于 std::span,它是别人的课。 :) 说真的,在我看来
std::span是最惯用的方式。 -
@RyanV.Bissell 是的,只读访问就可以了。我对
Mmap类的意思是,如果需要,它可以用于进行映射并提供非constspan类接口。