使用 ReadFile 时访问冲突读取位置
Posted
技术标签:
【中文标题】使用 ReadFile 时访问冲突读取位置【英文标题】:Access violation reading location when using ReadFile 【发布时间】:2017-04-08 09:21:25 【问题描述】:过去几个小时我一直在为以下问题苦苦挣扎:我尝试使用 CreateFile 和 ReadFile 方法读取文件。
代码如下:
char* Utils::ReadFromFile(wchar_t* path)
HANDLE hFile = CreateFile(
path, // long pointer word string file path (16 bit UNICODE char pointer)
GENERIC_READ, // access to file
0, // share mode ( 0 - prevents others from opening/readin/etc)
NULL, // security attributes
OPEN_EXISTING, // action to take on file -- returns ERROR_FILE_NOT_FOUND
FILE_ATTRIBUTE_READONLY, // readonly and offset possibility
NULL // when opening an existing file, this parameter is ignored
);
if (hFile == INVALID_HANDLE_VALUE)
std::cout << "File opening failed" << endl;
std::cout << "Details: \n" << Utils::GetLastErrorMessage() << endl;
CloseHandle(hFile);
hFile = NULL;
return nullptr;
LARGE_INTEGER largeInteger;
GetFileSizeEx(hFile, &largeInteger);
LONGLONG fileSize = largeInteger.QuadPart;
if (fileSize == 0)
std::cout << "Error when reading file size" << endl;
std::cout << "Details: \n" << Utils::GetLastErrorMessage() << endl;
CloseHandle(hFile);
hFile = NULL;
return nullptr;
cout << "File size: " << fileSize << endl;
char* bytesRead;
bytesRead = new char(fileSize);
int currentOffset = 0;
int attempts = 0;
int nBytesToBeRead = BYTES_TO_READ;
//DWORD nBytesRead = 0;
OVERLAPPED overlap;
errno_t status;
while (currentOffset < fileSize)
overlap.Offset = currentOffset;
if (fileSize - currentOffset < nBytesToBeRead)
nBytesToBeRead = fileSize - currentOffset;
status = ReadFile(
hFile, // file handler
bytesRead + currentOffset, // byted read from file
nBytesToBeRead, // number of bytes to read
NULL, // number of bytes read
&overlap // overlap parameter
);
if (status == 0)
std::cout << "Error when reading file at offset: " << currentOffset << endl;
std::cout << "Details: \n" << Utils::GetLastErrorMessage() << endl;
attempts++;
std::cout << "Attempt: " << attempts << endl;
if (attempts == 3)
cout << "The operation could not be performed. Closing..." << endl;
CloseHandle(hFile);
hFile = NULL;
return nullptr;
continue;
else
cout << "Read from offset: " << currentOffset;// << " -- " << overlap.InternalHigh << endl;
currentOffset += nBytesToBeRead;
if (currentOffset == fileSize)
cout << "File reading completed" << endl;
break;
CloseHandle(hFile);
return bytesRead;
运行此方法时,我得到了一些奇怪的结果:
-
曾经完美运行
我经常得到 currentOffset 变量和重叠的访问冲突读取位置。InternalHigh(我评论了最后一个),CallStack 中的最后一个方法是
msvcp140d.dll!std::locale::locale(const std::locale & _Right) 第 326 行 C++
有时该函数运行得很好,但是当我尝试退出主函数时,调用堆栈中的最后一个方法是访问冲突读取位置
ucrtbased.dll!_CrtIsValidHeapPointer(const void * block) 第 1385 行 C++
我彻底阅读了有关我使用的方法的 Windows 文档,并在 Internet 上查找了我能找到的任何解决方案,但没有任何结果。我不理解这种行为,多次运行 cod 时会出现不同的错误,因此我无法找到解决此问题的方法。
注意:我在重复调用中读取文件的原因无关紧要。我试着用一个电话来阅读,结果是一样的。
提前谢谢你
【问题讨论】:
将bytesRead = new char(fileSize);
更改为 bytesRead = new char[fileSize];
我不知道new char(fileSize);
应该做什么。我不知道它甚至会编译。
确实,这就是问题所在。我怎么会错过...谢谢
【参考方案1】:
您正在为 bytesRead 分配单个字符,而不是 fileSize 字符数组:
char* bytesRead;
bytesRead = new char(fileSize); // allocate a char and initialize it with fileSize value
bytesRead = new char[fileSize]; // allocate an array of fileSize chars
【讨论】:
天哪……就是这样……谢谢 您应该注意编译器警告。在这种情况下,您应该收到一个用于将 long long 缩小为 char 的文件。 这件事以后我一定会更加小心的以上是关于使用 ReadFile 时访问冲突读取位置的主要内容,如果未能解决你的问题,请参考以下文章
使用 memcpy 时出错:“访问冲突读取位置 0x0000000000000000”