I found an interesting material in the C # specification A.8 Dynamic memory allocation .
Slightly redid it to work with x64:
internal unsafe class Memory { // Heap API flags private const uint HEAP_ZERO_MEMORY = 0x00000008; // Heap API functions [DllImport("Kernel32")] private static extern IntPtr GetProcessHeap(); [DllImport("Kernel32")] private static extern int HeapSize(IntPtr hHeap, uint dwFlags, IntPtr lpMem); [DllImport("Kernel32")] private static extern IntPtr HeapAlloc(IntPtr hHeap, uint dwFlags, UIntPtr dwBytes); [DllImport("Kernel32")] private static extern IntPtr HeapReAlloc(IntPtr hHeap, uint dwFlags, IntPtr lpMem, UIntPtr dwBytes); [DllImport("Kernel32")] private static extern bool HeapFree(IntPtr hHeap, uint flags, IntPtr lpMem); // Handle for the process heap. This handle is used in all calls to the // HeapXXX APIs in the methods below. private static IntPtr ph = GetProcessHeap(); // Private instance constructor to prevent instantiation. private Memory() { } // Allocates a memory block of the given size. The allocated memory is // automatically initialized to zero. public static void* Alloc(uint size) { void* result = HeapAlloc(ph, HEAP_ZERO_MEMORY, new UIntPtr(size)).ToPointer(); if (result == null) throw new OutOfMemoryException(); return result; } // Copies count bytes from src to dst. The source and destination // blocks are permitted to overlap. public static void Copy(void* src, void* dst, int count) { byte* ps = (byte*)src; byte* pd = (byte*)dst; if (ps > pd) { for (; count != 0; count--) *pd++ = *ps++; } else if (ps < pd) { for (ps += count, pd += count; count != 0; count--) *--pd = *--ps; } } // Frees a memory block. public static void Free(void* block) { if (!HeapFree(ph, 0, new IntPtr(block))) throw new InvalidOperationException(); } // Re-allocates a memory block. If the reallocation request is for a // larger size, the additional region of memory is automatically // initialized to zero. public static void* ReAlloc(void* block, uint size) { void* result = HeapReAlloc(ph, HEAP_ZERO_MEMORY, new IntPtr(block), new UIntPtr(size)).ToPointer(); if (result == null) throw new OutOfMemoryException(); return result; } // Returns the size of a memory block. public static int SizeOf(void* block) { int result = HeapSize(ph, 0, new IntPtr(block)); if (result == -1) throw new InvalidOperationException(); return result; } } I’m still a native, so I’m asking experienced people to conduct code testing, which will mostly be a replacement for the standard byte array (byte []) in a multi-threaded application.
ps according to preliminary data HeapAlloc is faster than standard stackalloc. True professional benchmarks did not hold, I used stopwatch.