使用ReadFile时访问冲突读取位置

时间:2017-04-08 09:21:26

标签: c++

我在过去的几个小时里遇到了以下问题:我尝试使用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;
}

运行此方法时,我得到了一些奇怪的结果:

  1. 一次完美运作
  2. 我经常得到currentOffset变量的access违规读取位置和overlap.InternalHigh(我评论过最后一个),来自CallStack的最后一个方法是

      

    msvcp140d.dll!std :: locale :: locale(const std :: locale&amp; _Right)第326行C ++

  3. 有时候这个函数运行得很好,但是当我尝试使用CallStack中的最后一个方法退出main函数时,我得到了访问冲突读取位置

      

    ucrtbased.dll!_CrtIsValidHeapPointer(const void * block)第1385行C ++

  4. 我彻底阅读了关于我使用的方法的Windows文档,并检查了互联网上我找到的任何解决方案,但没有任何结果。我不明白这种行为,在多次运行cod时遇到不同的错误,因此我无法找到解决此问题的方法。

    注意:我在重复调用中读取文件的原因无关紧要。我试着用一个电话阅读,结果是一样的。

    提前谢谢

1 个答案:

答案 0 :(得分:0)

您为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