CreateFile2,WriteFile和ReadFile:如何强制执行16字节对齐?

时间:2016-10-25 16:47:51

标签: c++ dangling-pointer

我正在使用CreateFile2和WriteFile创建和编写一个文件,然后使用readfile一次读取16个字节到__m128i然后对它执行simd操作。在调试模式下工作正常,但在发布模式下抛出拒绝访问(0xc0000005)错误代码。根据我的经验,当我试图将非16字节对齐的东西推入16字节对齐的东西时,就会发生这种情况。但是,我不确定缺少16字节对齐的地方首先是它的丑陋头脑。

#define simd __m128i

是否在CreateFile2()调用中?

_CREATEFILE2_EXTENDED_PARAMETERS extend = { 0 };
extend.dwSize = sizeof(CREATEFILE2_EXTENDED_PARAMETERS);
extend.dwFileAttributes = FILE_ATTRIBUTE_NORMAL;
extend.dwFileFlags = /*FILE_FLAG_NO_BUFFERING |*/ FILE_FLAG_OVERLAPPED;
extend.dwSecurityQosFlags = SECURITY_ANONYMOUS;
extend.lpSecurityAttributes = nullptr;
extend.hTemplateFile = nullptr;

hMappedFile = CreateFile2(
    testFileName.c_str(),
    GENERIC_READ | GENERIC_WRITE,
    0,
    OPEN_ALWAYS,
    &extend);

...在WriteFile()调用中?

_OVERLAPPED positionalData;
positionalData.Offset = 0;
positionalData.OffsetHigh = 0;
positionalData.hEvent = 0;

bool writeCheck = WriteFile(
    hMappedFile,
    &buffer[0],
    vSize,
    NULL,
    &positionalData);

...在后面的ReadFile()调用中?

const simd* FileNodePointer(
    _In_ const uint32_t index) const throw()
{
    std::vector<simd> Node(8);

    _OVERLAPPED positionalData;
    positionalData.Offset = index;
    positionalData.OffsetHigh = 0;
    positionalData.hEvent = 0;

    ReadFile(
        hMappedFile,
        (LPVOID)&Node[0],
        128,
        NULL,
        &positionalData);

    return reinterpret_cast<const simd*>(&Node[0]);
}

如何在此强制执行16字节对齐?

谢谢!

1 个答案:

答案 0 :(得分:1)

TL; DR你有一个经典的&#34;免费使用&#34;错误。

这些功能都不需要16字节对齐。如果启用了缓冲,它们根本不关心对齐,如果启用了直接I / O,它们需要页面对齐,这比16个字节要严格得多。

如果您的数据缓冲区未对齐,那是因为您以这种方式创建了它。文件I / O没有将缓冲区移动到内存中。

但您的访问冲突根本不是由对齐问题引起的,而是您从FileNodePointer返回的悬空指针:

return reinterpret_cast<const simd*>(&Node[0]);

指向具有自动生命周期的向量内容的指针,向量析构函数在函数返回过程中运行,并释放包含刚刚从文件中读取的数据的内存。