# Custom ImGui Memory Allocator Configuration for Engines

> Configure a custom ImGui memory allocator for your engine using SetAllocatorFunctions. Route ImGui heap operations through custom memory pools and trackers for precise control.

- Repository: [omar/imgui](https://github.com/ocornut/imgui)
- Tags: how-to-guide
- Published: 2026-07-30

---

**Dear ImGui allows complete replacement of its internal memory allocation functions via `ImGui::SetAllocatorFunctions()`, enabling game engines to route all ImGui heap operations through custom memory pools, trackers, or aligned allocators.**

Game engines integrating the popular immediate-mode GUI library Dear ImGui (ocornut/imgui) often require tight control over memory allocation for profiling, alignment constraints, or platform-specific heap requirements. The library exposes a clean C-style callback mechanism to override its default `malloc`/`free` usage without modifying core source files.

## Understanding ImGui's Allocation Architecture

Dear ImGui abstracts allocation through two function pointer types defined in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) at lines 288-289: **`ImGuiMemAllocFunc`** and **`ImGuiMemFreeFunc`**. These define the required signatures for custom allocation (`void* (*)(size_t, void*)`) and deallocation (`void (*)(void*, void*)`), respectively.

### Default Allocators and Configuration

By default, ImGui uses standard `malloc` and `free`. You can force the library to exclude these defaults entirely by defining **`IMGUI_DISABLE_DEFAULT_ALLOCATORS`** in your [`imconfig.h`](https://github.com/ocornut/imgui/blob/main/imconfig.h) (or via compiler flags), as documented in [`imconfig.h`](https://github.com/ocornut/imgui/blob/main/imconfig.h) lines 52-53. When this macro is defined, you must supply custom functions before creating any context, or the application will fail to link.

### Per-Context Storage

Each `ImGuiContext` stores its own allocator pointers, permitting multiple simultaneous contexts to use different memory strategies. As implemented in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), the allocator functions are stored at the context level, meaning you can isolate ImGui memory usage per subsystem if needed.

## Implementing Custom Allocators in Your Engine

To integrate your engine's memory manager with ImGui, follow this sequence precisely:

1. **Implement the callback functions** matching the `ImGuiMemAllocFunc` and `ImGuiMemFreeFunc` signatures.
2. **Optionally disable defaults** by defining `IMGUI_DISABLE_DEFAULT_ALLOCATORS` to prevent ImGui from linking against CRT heap functions.
3. **Install the allocator** by calling `ImGui::SetAllocatorFunctions()` **before** `ImGui::CreateContext()`—this is a hard requirement documented in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) line 1158.
4. **Create the context**, which will now route all internal allocations through your supplied functions.

### DLL Boundary Considerations

When compiling ImGui into a dynamic library (DLL), the heap is not shared across DLL boundaries. Every DLL that uses ImGui must call both **`SetCurrentContext()`** and **`SetAllocatorFunctions()`** to maintain consistent allocator state, as noted in [`imconfig.h`](https://github.com/ocornut/imgui/blob/main/imconfig.h) lines 25-26. Failure to do so will result in memory being freed through a different allocator than allocated it, causing immediate heap corruption.

## Complete Integration Example

The following pattern demonstrates forwarding allocations to an engine's pool allocator:

```cpp
// EngineMemory.h
struct EngineMemory {
    void* allocate(size_t size) { return myPool->alloc(size); }
    void  deallocate(void* ptr) { myPool->free(ptr); }
};

// ImGui allocator callbacks
static void* MyImGuiAlloc(size_t sz, void* user_data)
{
    return static_cast<EngineMemory*>(user_data)->allocate(sz);
}

static void MyImGuiFree(void* ptr, void* user_data)
{
    static_cast<EngineMemory*>(user_data)->deallocate(ptr);
}

// ---------------------------------------------------------------------
// Engine initialization - must run before any ImGui context creation
EngineMemory gEngineMemory;

void InitImGui()
{
    // Optionally ensure defaults are disabled in your imconfig.h:
    // #define IMGUI_DISABLE_DEFAULT_ALLOCATORS
    
    ImGui::SetAllocatorFunctions(MyImGuiAlloc, MyImGuiFree, &gEngineMemory);
    ImGui::CreateContext();  // Now uses custom allocator exclusively
}

```

For frame-based allocation strategies (such as linear "scratch" allocators), you can implement `MyImGuiAlloc` to obtain memory from the current frame's buffer and leave `MyImGuiFree` as a no-op, since ImGui automatically releases all memory when the context is destroyed.

## Summary

- **Hook early**: Always call `ImGui::SetAllocatorFunctions()` before `ImGui::CreateContext()` when using custom allocators.
- **Type safety**: Implement callbacks matching `ImGuiMemAllocFunc` (`void* (*)(size_t, void*)`) and `ImGuiMemFreeFunc` (`void (*)(void*, void*)`).
- **Configuration**: Define `IMGUI_DISABLE_DEFAULT_ALLOCATORS` in [`imconfig.h`](https://github.com/ocornut/imgui/blob/main/imconfig.h) to strip default `malloc`/`free` dependencies.
- **DLL safety**: Re-install allocators in every DLL boundary using `SetAllocatorFunctions()` alongside `SetCurrentContext()`.
- **Debug visibility**: Reference [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp) and [`imgui_internal.h`](https://github.com/ocornut/imgui/blob/main/imgui_internal.h) for internal context storage details when debugging allocator usage.

## Frequently Asked Questions

### When exactly must I call SetAllocatorFunctions?

You must call `ImGui::SetAllocatorFunctions()` **before** the first invocation of `ImGui::CreateContext()`. According to the source code in [`imgui.h`](https://github.com/ocornut/imgui/blob/main/imgui.h) line 1158, the allocator is captured during context creation and cannot be changed for an active context without destroying and recreating it.

### Can different ImGui contexts use different allocators?

Yes. Because `ImGuiContext` stores its own allocator function pointers as implemented in [`imgui.cpp`](https://github.com/ocornut/imgui/blob/main/imgui.cpp), you can create multiple contexts each with distinct allocators by calling `SetAllocatorFunctions()` before each `CreateContext()` call. This enables per-subsystem memory isolation.

### What happens if I disable default allocators but forget to set custom ones?

If you define `IMGUI_DISABLE_DEFAULT_ALLOCATORS` in [`imconfig.h`](https://github.com/ocornut/imgui/blob/main/imconfig.h) (lines 52-53) but fail to provide replacement functions, your build will fail at link time due to unresolved `malloc`/`free` symbols. The macro completely removes the default implementations from the compiled library.

### How do I handle SIMD alignment requirements in my custom allocator?

Your `ImGuiMemAllocFunc` implementation must return memory aligned to the requirements of your target platform (typically 16-byte for SSE or 32-byte for AVX). ImGui itself does not impose alignment requirements beyond standard C++ object alignment, but passing insufficiently aligned memory to ImGui functions that later feed into graphics APIs may cause crashes during vertex buffer uploads.