2016-10-25 4 views
0

私はCreateFile2とWriteFileを使ってファイルを作成して書きました。後でreadfileを使って、一度に16バイトを__m128iに読み込んでからsimd操作を実行します。デバッグモードで正常に動作しますが、リリースモードでアクセス拒否(0xc0000005)エラーコードがスローされます。私の経験では、16バイトで整列されていないものを16バイト整列されたものに変更しようとしているときに起こります。しかし、私は16バイトアラインメントの欠如が最初にその醜い頭を育てているのか分からない。CreateFile2、WriteFile、およびReadFile: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バイトアライメントを強制できますか?

ありがとうございます!

+0

デバッガはあなたに何を伝えますか?クラッシュのサイトから後方に作業して、問題の発生元を特定します。 – 1201ProgramAlarm

+0

キャストを取り除くと、暗黙的な変換で十分であり、reinterpret_castは危険です。コンパイラは、コードが単純化されたときに生涯エラーを検出する可能性が高くなります。 –

答えて

1

TL; DR古典的な "use after free"というエラーがあります。


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

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

しかし、あなたのアクセス違反がすべての位置合わせの問題によって引き起こされていないが、それはあなたが FileNodePointerから復帰ダングリングポインタです:

自動生涯、ベクトルデストラクタの実行を持つベクトルのコンテンツへのポインタをだ
return reinterpret_cast<const simd*>(&Node[0]); 

関数の戻り処理中に、読み込んだデータを含むメモリをファイルから解放します。

+0

注:あなたの発言は正しいですし、提示された私のコードの問題に対処します。ただし、ここで問題を解決する(つまり、関数の後に存在しなくなったポインタの代わりに__m128iのベクトルが返される)場合でも、同じアクセス違反が発生します。 FILE_FLAG_NO_BUFFERINGを使用するモデルに変更しました(4096バイトの倍数で、一度に4096バイトの倍数のインデックスで読み込みを行います)、出力が正しいことをデバッグモードで確認できます。リリースモードはまだ問題を表しています。何かご意見は? – MNagy

+0

@MNagyはい、私はベクトルが壊れている(SIMDで必要とされているようなオーバーライド型を割り当てることはできません)、ファイルへのアクセスはあなたの問題とはまったく関係ないと思います。 –

関連する問題