Я создаю и записываю файл с помощью 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-байтовое выравнивание?
Спасибо!
TL; DR У вас есть классическая ошибка «использовать после освобождения».
Ни одна из этих функций не требует 16-байтового выравнивания. Если буферизация включена, они вообще не заботятся о выравнивании, а если включен прямой ввод-вывод, они требуют выравнивания страницы, которое намного более ограничительно, чем 16 байтов.
Если ваш буфер данных не выровнен, это потому, что вы создали его таким образом. Файловый ввод / вывод не перемещает ваш буфер в память.
Но ваше нарушение доступа вовсе не вызвано проблемами с выравниванием, это болтающийся указатель, с которого вы возвращаетесь FileNodePointer
:
return reinterpret_cast<const simd*>(&Node[0]);
Это указатель на содержимое вектора с автоматическим временем жизни, деструктор вектора запускается во время процесса возврата функции и освобождает память, содержащую данные, которые вы только что прочитали из файла.
Других решений пока нет …