Skip to main content

Include/pymem.h

cpython 3.14 @ ab2d84fe1023/Include/pymem.h

Include/pymem.h declares the public-facing memory API. It splits allocations into three domains: PyMem_ (object memory, GIL must be held), PyMem_Raw_ (raw C heap, no GIL requirement), and PyObject_ (object allocator, usually pymalloc). Each domain can be replaced independently with PyMem_SetAllocator.

Map​

LinesSymbolRole
1-40PyMemAllocatorDomain, PyMemAllocatorExEnum and allocator struct for custom hooks
41-90PyMem_SetAllocator, PyMem_GetAllocatorAllocator injection/inspection API
91-120PyMem_Malloc, PyMem_Realloc, PyMem_FreeObject-domain allocator macros
121-145PyMem_RawMalloc, PyMem_RawCalloc, PyMem_RawFreeRaw-domain allocator functions

Reading​

Three allocation domains​

Domain prefixGIL requiredTypical backing
PyMem_Raw_Nomalloc
PyMem_Yespymalloc or malloc
PyObject_Yespymalloc

Pre-GIL or post-GIL code (signal handlers, finalizers before the interpreter is fully up) must use PyMem_Raw*. Using PyMem_* without holding the GIL is undefined behaviour.

PyMemAllocatorEx​

// CPython: Include/pymem.h:44 PyMemAllocatorEx
typedef struct {
void *ctx;
void* (*malloc) (void *ctx, size_t size);
void* (*calloc) (void *ctx, size_t nelem, size_t elsize);
void* (*realloc)(void *ctx, void *ptr, size_t new_size);
void (*free) (void *ctx, void *ptr);
} PyMemAllocatorEx;

A custom allocator is injected per-domain via PyMem_SetAllocator(domain, &alloc). The ctx pointer is passed as the first argument to every callback, allowing stateful allocators (arena pools, leak trackers).

PyMem_Malloc on size 0​

By contract PyMem_Malloc(0) returns a unique non-NULL pointer. Code that conditionally checks the return value for NULL to detect failure must also check size.

gopy notes​

The Go runtime manages memory automatically. gopy does not expose PyMem_ APIs to user code; internally, Python object structs are allocated with new(T) or sync.Pool for hot paths. The PyMemAllocatorEx hook has no Go analogue.