我正在重新学习C ++,我需要使用内存映射文件。我决定使用boost(因为它似乎是实体库)。
我创建了一个映射到双精度数组的内存映射文件,并写入此数组中的第一个double。在磁盘文件中包含前四个字节中的一些数据,其余部分归零,这对我来说很奇怪,因为我在C ++中获取指向内存位置的指针,在大多数情况下我必须假设它包含垃圾。
我是否有任何保证新创建的内存映射文件将被清零(至少在Linux上)?我没有找到任何参考。
BOOST_AUTO_TEST_CASE(OpenMMapFile){
boost::iostreams::mapped_file file;
boost::iostreams::mapped_file_params params;
params.path = "/tmp/mmaptest-1";
params.mode = std::ios::in | std::ios::out;
params.new_file_size = 10*sizeof(double);
file.open(params);
double* data = static_cast<double*>((void*)file.data());
data[0] = 12;
file.close();
}
这是文件内容:
cat /tmp/mmaptest-1 | base64
AAAAAAAAKEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA =
编辑
正如@Zan指出的那样 - boost实际上使用ftruncate来调整mmaped文件的大小,因此保证了归零(至少在Linux上)。
答案 0 :(得分:3)
内存映射文件包含文件中的内容。
如果是新文件,它已扩展到正确的大小,扩展名将包含零。扩展文件通常使用ftruncate函数完成。
ftruncate联机帮助页说:
If the file previously was larger than this size, the extra data is lost. If the file previously was shorter, it is extended, and the extended part reads as null bytes ('\0').
所以是的,保证零。
答案 1 :(得分:-1)
我认为为了实现映射的地址空间实际上是由磁盘空间而不是稀疏文件备份的,我们会将文件归零。 这很慢,特别是如果你想在前面创建一个大的地址空间, 它可能永远不会被完全使用 - 只是为了你可以在这个地址空间中分配许多对象。 他们正在这样做,因为在写入内存映射的稀疏文件时,UNIX上没有可用的方法来处理磁盘空间(暂时忽略像setjmp / longjmp这样的病态解决方案)。 但是你仍有可能某些其他进程截断磁盘上的文件, 在这种情况下,前面提到的问题再次出现。
不幸的是,他们也在Windows上执行此操作(分配与地址空间大小匹配的磁盘空间而不是使用稀疏文件),其中存在结构化异常处理。