2016-10-25 55 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您有一個經典的「免費使用」錯誤。


這些函數都不需要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所需的過度對齊類型),文件訪問與您的問題完全無關。 –