Setting `SDL_calloc` to `NativeMemory.Alloc(nuint, nuint)` leads to memory corruption

1 day ago 2
ARTICLE AD BOX

Using P/Invoke with SDL 3.4.0 (win32-x64 prebuilt binaries), I was curious what differences, if any, would manifest using NativeMemory rather than the built-in SDL implementation.

I have the following import:

[LibraryImport("SDL3")] [UnmanagedCallConv(CallConvs = [typeof(CallConvCdecl)])] [return: MarshalAs(UnmanagedType.U1)] public static partial bool SDL_SetMemoryFunctions ( delegate* unmanaged[Cdecl]<nuint, void*> malloc, delegate* unmanaged[Cdecl]<nuint, nuint, void*> calloc, delegate* unmanaged[Cdecl]<void*, nuint, void*> realloc, delegate* unmanaged[Cdecl]<void*, void> free );

And I have the following callback stub (since NativeMethods.Alloc(nuint, nuint) does not have the UnmanagedCallersOnly attribute):

[UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)])] private static void* CallocCallback(nuint elementCount, nuint elementSize) { if (elementCount == 0U) { elementCount = 1U; } if (elementSize == 0U) { elementSize = 1U; } return NativeMemory.Alloc(elementCount, elementSize); }

I included the checks on elementCount and elementSize to match the documented behavior of SDL_calloc. I have similar stubs for malloc, realloc, and free.

I am setting the SDL memory functions, before calling SDL_Init:

NativeMethods.SDL_SetMemoryFunctions ( &MallocCallback, &CallocCallback, &ReallocCallback, &FreeCallback );

When I replace SDL_calloc with CallocCallback, my program is crashing with an ExecutionEngineException at seemingly random points during SDL_Init (Windows 10, Visual Studio Community 2026, .NET 10, Debug build running in the debugger).

Sometimes the program is crashing very quickly, with only a few MB of memory being allocated; other times the program is allocating 2+ GB before hanging (and eventually crashing). Inspecting elementCount and elementSize don't show any unexpected results. SDL_Init(SDL_INIT_VIDEO) consistently fails to complete if SDL_calloc has been assigned to CallocCallback.

I have tried omitting the guards on elementCount and elementSize, and tried wrapping the whole thing in a try/catch block, all to no avail.

If I use SDL_GetOriginalMemoryFunctions to get the built-in SDL_calloc before calling SDL_SetMemoryFunctions, replacing all of the other functions except calloc (leaving that as the built-in SDL_calloc), then everything (apparently) initializes smoothly.

I have even confirmed that MallocCallback, ReallocCallback and FreeCallback are indeed being invoked, each calling the relevant NativeMemory method. Only the calloc implementation causes this random crash.

Am I getting something wrong with this particular method, or is there some fix I can implement? I'm unclear why only this one memory function is causing issues.

Also, just to be clear, I don't have a particular reason to use NativeMemory, it was just a test that everything else was hooked up properly to be able to (potentially) implement other allocators if/when needed.

Read Entire Article