Reputation: 1207
CreateFileMapping error code 8.Not enough storage is available to process this command. Im trying to create file mapping with 4 Gb (0xFFFFFFFF) on 64bit 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"));
How can i solve this "ERROR 8" problem?
Upvotes: 1
Views: 1670
Reputation: 941465
CreateFileMapping(..., HIWORD(UBS_MEM_SIZE), LOWORD(UBS_MEM_SIZE), ...)
The LO/HIWORD macros generate a WORD, a 16-bit value. You are asking for a 0xffff0000ffff memory-mapped file. That's 282 terabytes. Current x64 processors are limited to a 48-bit VM-address, most top out at 8 terabytes. So yes, error 8 (ERROR_NOT_ENOUGH_MEMORY) is entirely expected.
Don't use those macros. You can use LARGE_INTEGER as an alternative:
LARGE_INTEGER size;
size.QuadPart = UBS_MEM_SIZE;
HANDLE hMapObject = CreateFileMapping(..., size.HighPart, size.LowPart, ...);
Upvotes: 5
Reputation: 9317
The HIWORD
and LOWORD
macros are intended to extract the high and low 16-bit words from a 32-bit DWORD
. CreateFileMapping
, on the other hand, expects two DWORD
s that together make up a 64-bit unsigned integer, which is the size of the mapping object.
Both HIWORD(UBS_MEM_SIZE)
and LOWORD(UBS_MEM_SIZE)
yield 0xffff
(the two 16-bit halves), which are then converted to 32-bit unsigned integers (which is what the function expects).
So, what you're actually doing is asking for a file mapping of size 0x0000ffff0000ffff
. This is more than 255 TB
. Since you're using INVALID_HANDLE_VALUE
, this has to be backed by RAM or the system page file; I doubt you have that much available in there.
If UBS_MEM_SIZE
is always 32-bit, you can simply use
HANDLE hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr,
PAGE_READWRITE, 0, UBS_MEM_SIZE,
TEXT("dllmemfilemap"));
If you actually need to handle sizes over 4 GB
, you can do something like this:
HANDLE hMapObject = CreateFileMapping(INVALID_HANDLE_VALUE, nullptr, PAGE_READWRITE,
static_cast<DWORD>(UBS_MEM_SIZE >> 32), static_cast<DWORD>(UBS_MEM_SIZE),
TEXT("dllmemfilemap"));
Make sure UBS_MEM_SIZE
actually has a type larger than 32-bit (even if its value may be less than that), since otherwise shifting by 32 bits is undefined behaviour in C++. So, if you want to use the second variant above with your initial value, it will have to be something like
#define UBS_MEM_SIZE 0xFFFFFFFFull
(By the way, use const
...)
To make it safer, I'd wrap the call into something like this:
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);
}
This way, you don't need to remember any tricky details about bits, shifts and integer type sizes.
Upvotes: 4