0

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 バイト アラインメントを強制するにはどうすればよいですか?

ありがとう!

4

1 に答える 1

1

TL;DR 古典的な「解放後の使用」エラーがあります。


これらの関数はいずれも、16 バイトのアラインメントを必要としません。バッファリングが有効になっている場合、それらはアラインメントをまったく気にしません。また、ダイレクト I/O が有効になっている場合、16 バイトよりもはるかに制限的なページ アラインメントが必要になります。

データ バッファーが整列されていない場合は、そのように作成したことが原因です。ファイル I/O がメモリ内のバッファを移動していません。

しかし、あなたのアクセス違反はアライメントの問題が原因ではなく、あなたが返すダングリングポインタですFileNodePointer:

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

これは、自動有効期間を持つベクターのコンテンツへのポインターです。ベクター デストラクタは、関数のリターン プロセス中に実行され、ファイルから読み取ったばかりのデータを含むメモリを解放します。

于 2016-10-25T16:58:42.617 に答える