libstddjb
libskarnet
skalibs
Software
skarnet.org

# The `stralloc` library interface

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

## General information

`stralloc` is the preferred skalibs way of storing objects into heap memory. It focuses on strings of char, which is the generic way to handle any object. For easy structure manipulation, the genalloc series of functions can be used; those functions are mostly macros wrapping calls to their stralloc counterparts.

A stralloc is a structure containing the following fields:

- s: a pointer to a zone of heap memory. The stralloc functions internally manipulate those via the alloc series of functions. It is recommended to never modify that field manually.
- len: the used length of the allocated zone. It is the only field that the user can modify directly.
- a: the number of allocated bytes. The user should never have to access that field, because the memory allocation management should be entirely transparent. len cannot exceed a: if an operation needs a bigger len, it will automatically reallocate as needed.

The benefits of using stralloc are as follows:

- Memory allocation is performed on-demand and automatically, with a suitable size. Heuristics are used to accommodate constantly growing strings while minimizing the amount of needed reallocations.
- If every heap-allocated object is represented by a stralloc, then it is very easy to identify what pointer is in the heap. When you stop using a pointer p, should you free it ? Sometimes it's not easy to find out. When you stop using a stralloc sa, you know you must call `stralloc_free(&sa)`. Store your strong references as strallocs and weak references as simple pointers, and never free simple pointers. This policy allows me to boast that no skarnet.org software has ever leaked memory.
- Repeated for emphasis: the golden rule for programming with strallocs is every pointer to the heap must be owned by a stralloc. Every pointer you handle yourself either does not point to the heap, or is weak. That sometimes implies unusual programming practices, such as having storage separated from structure, but it's hands down the easiest way to keep control of your heap in complex situations.
- The indirection layer makes weak references immune to reallocation troubles. The s field may change when a reallocation happens, but the stralloc structure's address never changes.

A stralloc can be declared anywhere: static/global data, stack or heap. (Of course, as a general rule, you should favor the stack whenever possible.) A stralloc should be initialized to STRALLOC_ZERO before its first use.

## Functions

`int stralloc_catb (stralloc *sa, char const *s, size_t len)`
Appends the len bytes pointed to by s to the end of the memory zone handled by *sa, automatically allocating more memory if needed. Returns 1 if it succeeds, and 0 if it fails.

`void stralloc_free (stralloc *sa)`
Frees *sa, i.e. calls alloc_free on sa→s then zeroes the structure. *sa is then reusable. However, it is not good practice to call this function if you're going to reuse *sa soon: it takes time and causes memory fragmentation. Just setting sa→len to 0 allows you to instantly reuse the allocated block of memory.

The above are the most important and fundamental functions of `skalibs/stralloc.h`. Other functions can be found in this header and their prototypes are self-explaining.