docs/Writerside/topics/allocator.h.md

Sat, 08 Feb 2025 14:13:59 +0100

author
Mike Becker <universe@uap-core.de>
date
Sat, 08 Feb 2025 14:13:59 +0100
branch
docs/3.1
changeset 1169
6a33a5648027
parent 1146
151c057faf7c
permissions
-rw-r--r--

add documentation for allocator.h

relates to #451

# Allocator

The allocator interface provides a mechanism to implement own custom allocators 
that can also be used in many other function in UCX.

A default allocator implementation using the stdlib functions is
available via the global symbol `cxDefaultAllocator`
and UCX also provides a [memory pool](mempool.h.md) implementation.
You are free to add additional own custom implementations.
A general sketch that illustrates how to do this can be found [below](#custom-allocator).

## Overview

```C
void *cxMalloc(const CxAllocator *allocator, size_t n);

void *cxCalloc(const CxAllocator *allocator,
               size_t nmemb, size_t size);

void *cxRealloc(const CxAllocator *allocator, void *mem, size_t n);

void *cxReallocArray(const CxAllocator *allocator, void *mem,
                     size_t nmemb, size_t size);

int cxReallocate(const CxAllocator *allocator, void **mem, size_t n);

int cxReallocateArray(const CxAllocator *allocator, void **mem,
                      size_t nmemb, size_t size);
    
void cxFree(const CxAllocator *allocator, void *mem);

int cx_reallocate(void **mem, size_t size);

int cx_reallocatearray(void **mem, size_t nmemb, size_t size);

// predefined allocator that uses stdlib functions
CxAllocator *cxDefaultAllocator;
```

> All UCX functions that are not _explicitly_ designed for taking an allocator argument
> (recognizable by a `_a` suffix in the function's name) do support a `NULL` argument
> in which case the `cxDefaultAllocator` will be used.

## Description

The functions `cxMalloc()`, `cxCalloc()`, `cxRealloc()`, `cxReallocArray()`, and `cxFree()`
invoke the memory management functions specified in the `allocator` and should behave like
their respective stdlibc pendants.
Implementations of the allocator interface are strongly encouraged to guarantee this behavior,
most prominently that invocations of `cxFree()` with a `NULL`-pointer for `mem` are ignored
instead of causing segfault error.

Additionally, UCX provides the functions `cxReallocate()` and `cxReallocateArray()`, as well as
their independent pendants `cx_reallocate()` and `cx_reallocatearray()`.
All those functions solve the problem that a possible reallocation might fail,
leading to a quite common programming mistake:

```C
// common mistake - mem will be lost hen realloc() returns NULL
mem = realloc(mem, capacity + 32);
if (mem == NULL) // ... do error handling
```

The above code can be replaced with `cx_reallocate()` which keeps the pointer intact and returns an error code instead.

```C
// when cx_reallocate() fails, mem will still point to the old memory
if (cx_reallocate(&mem, capacity + 32)) // ... do error handling
```

> Please pay special attention to always use `cxFree()` and the  `cxRealloc()`-family of functions
> with the **same** allocator that was used to allocate the memory.
{style="warning"}

## Custom Allocator

If you want to define your own allocator, you need to initialize the `CxAllocator` structure
with a pointer to an allocator class (containing function pointers for the memory management
functions) and an optional pointer to custom data. An example is shown below:

```c

struct my_allocator_state {
    // ... some internal state ...
};

static cx_allocator_class my_allocator_class = {
        my_malloc_impl,
        my_realloc_impl, // all these functions are somewhere defined
        my_calloc_impl,
        my_free_impl
};

CxAllocator create_my_allocator(void) {
    CxAllocator alloc;
    alloc.cl = &my_allocator_class;
    struct my_allocator_state *state = malloc(sizeof(*state));
    // ... initialize state ...
    alloc.data = state;
    return alloc;
}

void destroy_my_allocator(CxAllocator *al) {
    struct my_allocator_state *state = al->state;
    // ... destroy state --
    free(state);
}
```

<seealso>
<category ref="apidoc">
<a href="https://ucx.sourceforge.io/api/allocator_8h.html">allocator.h</a>
</category>
</seealso>

mercurial