Reference counting with C

For the purposes of this post, a very simple scenario is going to be considered. Given a Model structure that holds a pointer to a Mesh structure, the issue to be addressed is to whether or not there are references to a particular Mesh. Once all Models that reference a Mesh have been freed we can safely free the Mesh.

In order to achieve this we are going to store a reference count for each Mesh. Rather than keep a separate structure of reference counts elsewhere it’s possible to store the count with the allocated memory for the structure. To do this rather than calling malloc and free we wrap these functions inside a few analogous reference counting functions.

void* REF_alloc(size_t size)

When a structure is newly created REF_alloc is used

void* REF_addRef(void* ptr)

This function add a reference to an existing structure

void REF_free(void* ptr)

This is the most useful function as it will reduce the reference count, and only if it reaches zero will it actually free the structure.

REF_alloc is used exactly like malloc except that it actually allocates a little more memory than required

typedef struct REF_mem {
int refs;
int padding; // 8 byte alignment for following structs
} REF_mem;

This little structure is placed just before your data. Looking at REF_addRef

void* REF_addRef(void* ptr)
{
REF_mem* ref = ((REF_mem*)ptr) -1;
ref->refs++;
return ptr;
}

Given that your allocated pointer points to the data structure when accessing the reference counting structure some simple pointer arithmetic is needed, as the pointer above ( ref ) has the type of REF_mem subtracting 1 from the data pointer, means we get to the actual start of the allocated memory where the reference counting structure is located.

This simple technique keeps the reference counting out of the way, the only caveat is obviously that you have to remember to add a reference whenever another structure is relying on a particular structures existence.

A working example can be downloaded here, just to make things clearer.

Leave a Reply

Your email address will not be published. Required fields are marked *