Код ошибки CreateFileMapping 8

Код ошибки CreateFileMapping 8. Недостаточно памяти для обработки этой команды. Я пытаюсь создать сопоставление файлов с 4 ГБ (0xFFFFFFFF) на 64-битной Win10 Visual C ++.

#define UBS_MEM_SIZE 0xffffffff

HANDLE hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr,
PAGE_READWRITE, HIWORD(UBS_MEM_SIZE), LOWORD(UBS_MEM_SIZE),
TEXT("dllmemfilemap"));

Как я могу решить эту проблему «ОШИБКА 8»?

1

Решение

   CreateFileMapping(..., HIWORD(UBS_MEM_SIZE), LOWORD(UBS_MEM_SIZE), ...)

Макросы LO / HIWORD генерируют WORD, 16-битное значение. Вы запрашиваете отображенный в памяти файл 0xffff0000ffff. Это 282 терабайта. Текущие процессоры x64 ограничены 48-битным виртуальным адресом, максимальный размер которого составляет 8 терабайт. Так что да, ошибка 8 (ERROR_NOT_ENOUGH_MEMORY) вполне ожидаема.

Не используйте эти макросы. Вы можете использовать LARGE_INTEGER в качестве альтернативы:

LARGE_INTEGER size;
size.QuadPart = UBS_MEM_SIZE;
HANDLE hMapObject = CreateFileMapping(..., size.HighPart, size.LowPart, ...);
4

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

HIWORD а также LOWORD макросы предназначены для извлечения старших и младших 16-битных слов из 32-битных DWORD, CreateFileMappingс другой стороны, ожидает двух DWORDs вместе составляют 64-битное целое число без знака, которое является размером объекта сопоставления.

И то и другое HIWORD(UBS_MEM_SIZE) а также LOWORD(UBS_MEM_SIZE) Уступать 0xffff (две 16-битные половины), которые затем преобразуются в 32-битные целые числа без знака (что и ожидает функция).

Итак, что вы на самом деле делаете, так это запрашиваете отображение размера файла 0x0000ffff0000ffff, Это больше чем 255 TB, Так как вы используете INVALID_HANDLE_VALUEэто должно быть подкреплено ОЗУ или файлом системной страницы; Я сомневаюсь, что у вас есть так много там

Если UBS_MEM_SIZE всегда 32-битный, вы можете просто использовать

HANDLE hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr,
PAGE_READWRITE, 0, UBS_MEM_SIZE,
TEXT("dllmemfilemap"));

Если вам действительно нужно обрабатывать размеры более 4 GBВы можете сделать что-то вроде этого:

HANDLE hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE,
static_cast<DWORD>(UBS_MEM_SIZE >> 32), static_cast<DWORD>(UBS_MEM_SIZE),
TEXT("dllmemfilemap"));

Удостовериться UBS_MEM_SIZE на самом деле имеет тип больше 32-битного (даже если его значение может быть меньше этого), так как в противном случае сдвиг на 32 бита — неопределенное поведение в C ++. Итак, если вы хотите использовать второй вариант выше с вашим начальным значением, это должно быть что-то вроде

#define UBS_MEM_SIZE 0xFFFFFFFFull

(Кстати, используйте const…)

Чтобы сделать его более безопасным, я бы обернул вызов примерно так:

inline HANDLE MyCreateMapping(unsigned long long size, LPCTSTR name)
{
return CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE,
static_cast<DWORD>(size >> 32), static_cast<DWORD>(size), name);
}

Таким образом, вам не нужно запоминать хитрые детали о битах, сдвигах и размерах целочисленных типов.

3

По вопросам рекламы [email protected]