使用 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 时访问冲突读取位置的主要内容,如果未能解决你的问题,请参考以下文章

使用 ReadFile 对内存位置的无效访问

使用 memcpy 时出错:“访问冲突读取位置 0x0000000000000000”

C0000005: 读取位置 0xCCCCCCCC 时发生访问冲突

访问冲突读取位置尝试获取系统时间时

C ++访问冲突读取位置0xcdcdcdcd调用函数时出错

怎样使用ReadFile读取文本文件?