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.
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
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
- 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
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.
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.