gpt4 book ai didi

c++ - 处理无法映射到 Win32 中的一个 View 的大文件时出现访问冲突

转载 作者:行者123 更新时间:2023-11-28 03:52:00 24 4
gpt4 key购买 nike

早上好,我正在尝试编写一个 cMemoryMappedFile 类来处理无法映射到 Win32 中的一个 View 的大文件。代码位于 pastebin url .

在 GetPointer() 中,我们尝试根据需要仔细映射和取消映射文件区域。我们在标有注释的行上的 GetPointer() 中遇到访问冲突//如果调整后的 ptr 是错误的 ptr,则会在此处崩溃。

测试程序是:

int TotalKeys = 2709783;
try {
mmapFile = new cMemoryMappedFile(TotalKeys * 54 + 1);
}
catch (cException e) {
printf("catch cMemoryMappedFile\n");
throwl
}

for (i = 0; i < 50000; i++) {
mmapFile->GetPointer(i * 54);
}

当 i 等于 28521 并且 i * 54 = 1540134 时,我们得到一个访问冲突读取位置 0x0024000。 MEM_BLOCK_SIZE在MapViewOfFile要求的64K对齐上,MEM_BLOCK_SIZE = 65536 * 2。我们运行的是Windows XP Professional Version 2002 Service Pack 3,32位版本。令人费解的是,我们正在尝试在文件映射中移动 map View 。如果您愿意,请提出访问冲突的原因。

谢谢。

最佳答案

这个计算似乎过于复杂。

char * cMemoryMappedFile::GetPointer(int n){
unsigned int baseoff;
if( n < MEM_BLOCK_SIZE / 2)
{
baseoff = 0;
}
else
{
baseoff = ((n + MEM_BLOCK_SIZE / 4) &
(~(MEM_BLOCK_SIZE / 2 - 1))) - MEM_BLOCK_SIZE / 2;
}
...

据我所知,n 是文件中所需的偏移量,baseoff 是我们实际映射的第一个地址。我们想要最大的 baseoff <= n,其中 baseoffMEM_BLOCK_SIZE 的倍数。那么如何:

    unsigned int baseoff = (n / MEM_BLOCK_SIZE) * MEM_BLOCK_SIZE;

后来:

    MapPtr = (char*)::MapViewOfFile(hMapping, FILE_MAP_WRITE | FILE_MAP_READ, 0,
baseoff, mappedlength);

您应该检查 MapViewOfFile 的结果。

不清楚您想要的返回值是什么。我假设 adjustedptr + n 应该指向最初请求的字节。但是随后您尝试访问 *adjustedptr,当基本偏移量大于 MEM_BLOCK_SIZE 时,不能保证它是 View 的一部分。我认为您希望 printf 使用 *(adjustedptr + n)adjustedptr[n]。或者您可能正在尝试访问实际映射的第一个字节,即 adjustedptr[baseoff]

关于c++ - 处理无法映射到 Win32 中的一个 View 的大文件时出现访问冲突,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5156381/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com