I need to allocate a certain space in memory, and I have been using VirtualAlloc for this.
However, I have increasingly noticed that VirtualAlloc returns an address that exceeds 32 bits, though always less than 33 bits.
The consequence is that when I copy data to this memory address, the computer crashes into a BSOD.
I am using 64-bit windows and a 64-bit Python. I suspect that the program that copies data to the memory is only equipped to handle 32 bits. Is there is a way to enforce VirtualAlloc to provide an address within 32 bits?
I am using Python, specifically the ctypes package to call VirtualAlloc, see code below.
Executing this code multiple times changes the address, so repeatedly calling the function below will eventually result in an address below 32 bits. However, I am looking for the cause of and a fail-safe solution to the problem. Any help would be greatly appreciated.
import ctypes
mem_commit = 0x1000
page_readwrite = 0x4
size_bytes = 200000 # Allocation sizes are usually around this value
ctypes.windll.kernel32.VirtualAlloc.argtypes = [
ctypes.c_void_p, ctypes.c_long, ctypes.c_long, ctypes.c_long]
ctypes.windll.kernel32.VirtualAlloc.restype = ctypes.c_int
addr = ctypes.windll.kernel32.VirtualAlloc(
0, ctypes.c_long(size_bytes), mem_commit, page_readwrite)
Note that I free up the memory afterwards using VirtualFree.
It is possible to enforce a memory allocation with
VirtualAllocstarting on a 32-bits address memory as long as there is enough free space at this range. Looking in the msdoc we have the following function signature:And the following description for
lpAddress:So you can choose the address with this parameter. In your case, you specified 0 for
lpAddressand it is considered as NULL value.Furthermore, you must consider that if you choose the memory address you have to ensure that the space is free or
VirtualAllocwill not give you the space.Also, you use
mem_commitwithoutmem_reserveand the msdoc says:A better option would be to use 0x3000 (MEM_COMMIT|MEM_RESERVE) for
flAllocationTypeFinally, you certainly could use a 64-bits address but you set the result type of
VirtualAlloctoc_intand on Windows, this is an alias for a signed 32 bitsc_long. So a 64-bits address returned byVirtualAllocwould be truncated thus you would use a wrong address to copy your data.