【发布时间】:2018-09-08 20:33:24
【问题描述】:
我正在尝试将文件从本地磁盘映射到内存,以便我的程序可以访问文件内容。当对文件调用 mmap 时(大小略低于 100kB),我在调试器中查看从 mmap 返回的地址开始的内存,内存内容与文件内容不匹配(均以十六进制查看)。这不是字节交换问题。只有内存中的前 2 个字节与实际文件匹配,其余内容不匹配。
当我对包含字符串的小文件(例如:“hello world”)重复相同的操作时,在调试器中查看的内存与文件的内容完全匹配(再次以十六进制查看)。
我尝试使用 MAP_PRIVATE 而不是 MAP_SHARED,但结果相同。我怎样才能让它与我更大的文件一起使用?
我在 Ubuntu 17.10 中使用 Eclipse 4.7.2 + CDT 并使用 GDB 进行调试。
#include <iostream>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <string>
#include <unistd.h>
#include <sys/mman.h>
int main()
{
void* MapAddr = NULL;
char* pData = NULL;
struct stat FileProps;
int FileDes = 0;
const char* fileNameAndPath = "/home/Test/testfile.txt";
FileDes = open(fileNameAndPath, O_RDWR);
if (FileDes != -1)
{
if (fstat(FileDes, &FileProps) == 0)
{
MapAddr = mmap(NULL, FileProps.st_size, (PROT_READ | PROT_WRITE), MAP_SHARED, FileDes, 0);
if (MapAddr == (void*) -1)
{
std::cout << "init: mmap failed" << std::endl;
return 0;
}
}
}
pData = (char*) MapAddr;
std::cout << pData << std::endl;
return 0;
}
13:10:42 **** 为项目 mmapTest 构建配置调试 **** 做所有 构建文件:../src/mmapTest.cpp 调用:GCC C++ 编译器 g++ -O0 -g3 -Wall -c -fmessage-length=0 -MMD -MP -MF"src/mmapTest.d" -MT"src/mmapTest.o" -o "src/mmapTest.o" "../ src/mmapTest.cpp" 完成构建:../src/mmapTest.cpp
构建目标:mmapTest
调用:GCC C++ 链接器
g++ -o "mmapTest" ./src/mmapTest.o
完成构建目标:mmapTest
13:10:46 构建完成(耗时 4s.438ms)
【问题讨论】:
-
我想您知道该程序使用非标准功能。您是否出于某种原因要将文件读入映射内存而不是堆中的内存?做后者很容易,并且可以便携地完成。
-
感谢您提供可编译的代码示例。您能否也说明您是如何重现该问题的?
-
但是程序有效吗?
nmap()通过分页工作,调试器可能会也可能不会强制这样做。 -
JD - mmap 是非标准的,还是我正在做的其他事情?我正在尝试将 Windows 函数 CreateFileMapping 移植到 Linux。我的目标是从文件中取出数据,将其映射到内存中,然后将该内存映射到结构指针。有没有更好的方法来做到这一点?
-
@JiveDadson 它在问题中描述的平台上编译。我不明白你想表达什么样的观点,或者为什么它在这种情况下会有所帮助