CreateFile2, WriteFile и ReadFile: как применить принудительное выравнивание 16 байтов?

Я создаю и записываю файл с помощью 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-байтовое выравнивание?

Спасибо!

0

Решение

TL; DR У вас есть классическая ошибка «использовать после освобождения».


Ни одна из этих функций не требует 16-байтового выравнивания. Если буферизация включена, они вообще не заботятся о выравнивании, а если включен прямой ввод-вывод, они требуют выравнивания страницы, которое намного более ограничительно, чем 16 байтов.

Если ваш буфер данных не выровнен, это потому, что вы создали его таким образом. Файловый ввод / вывод не перемещает ваш буфер в память.

Но ваше нарушение доступа вовсе не вызвано проблемами с выравниванием, это болтающийся указатель, с которого вы возвращаетесь FileNodePointer:

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

Это указатель на содержимое вектора с автоматическим временем жизни, деструктор вектора запускается во время процесса возврата функции и освобождает память, содержащую данные, которые вы только что прочитали из файла.

1

Другие решения

Других решений пока нет …

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector