skalibs: the alloc library interface
Keywords: skalibs c unix alloc library libstddjb

libstddjb
libskarnet
skalibs
Software
skarnet.org

# The `alloc` library interface

The following functions are declared in the `skalibs/alloc.h` header, and implemented in the `libskarnet.a` or `libskarnet.so` library.

## General information

`alloc` is the skalibs heap memory manager. It's actually a wrapper for the malloc() series of functions; it unifies a few system-dependent `malloc` behaviours. It's also the API to implement and preload if for some reason you need to plug in your own allocator: replacing `alloc()` is much easier than replacing `malloc()` safely.

As a general rule, you should not be using the `alloc` interface directly. Allocating and freeing individual cells in the heap is a recipe for heap fragmentation, as well as cell tracking nightmares leading to memory leaks. You should use the higher-level stralloc and genalloc interfaces to handle dynamic arrays of objects.

C's lack of automatic management of heap memory is not a drawback: it's a feature of the language. It allows for code that is one or two orders of magnitude faster than the equivalent in a higher-level language, and very low on resources consumption. However, it requires more attention from the programmer. Good APIs can significantly reduce the difficulty of keeping track of every heap-allocated cell, and every smart programmer should favor them over basic interfaces like `malloc()`.

`alloc` is used internally by skalibs to implement stralloc, and nowhere else.

## Functions

`void *alloc (size_t len)`
Allocates a block of len bytes in the heap and returns a pointer to the start of the block (or NULL if it failed). If len is 0, the function returns a unique pointer that cannot be written to, but that is not null. Note that this is different from the required C99 behaviour for `malloc()`.

`void alloc_free (void *p)`
Frees the block of heap memory pointed to by p.

`int alloc_realloc (char **p, size_t newlen)`
Redimension the block of heap memory pointed to by *p to newlen bytes. The block may have to be moved, in which case *p will be modified. Normally returns 1; if an error occurred, returns 0 and sets errno, and neither *p nor its contents are modified. Note that p must be a pointer to a `char *`, because polymorphism isn't possible here (for reasons that have to do with pointer representation in C).

`int alloc_re (char **p, size_t oldlen, size_t newlen)`
Legacy interface for reallocation. It works like `alloc_realloc`, except that the original block length must be provided as the oldlen argument.