12. Memory Collections
Memory-allocated things are managed in a data type known
as a collection
. Data allocated in a collection can be
then used on things like targets, ramp trees, phrases, and
extra things needed by behaviors.
12.1. Struct Declarations
typedef struct gest_collection gest_collection;
A collection is a linked list of generic pointers.
<<struct_collection_entry>>
struct gest_collection {
struct gest_entry *tail;
int nitems;
};
A linked list entry contains a generic pointer and an optional destructor callback that can free any additional memory allocated and bound to the pointer by the user.
struct gest_entry {
void *ptr;
void (*free)(void *);
struct gest_entry *prev;
};
12.2. Initialization
The collection is initialized with collection_init
.
static void collection_init(gest_collection *col);
static void collection_init(gest_collection *col)
{
col->tail = NULL;
col->nitems = 0;
}
12.3. Allocating Memory
Anytime Gest needs to allocate memory, the gesture system uses an instance of the allocator.
12.3.1. Allocation with Destructor Callback
The core function for memory allocation is
collection_alloc_dtor
. In addition to providing the size,
an a user-defined destructor callback function. Note that
the allocated memory here is already being managed, and that
this is only used for any additional memory allocated inside
of it.
static void * collection_alloc_dtor(gest_collection *col,
size_t sz,
void (*free)(void*));
static void * collection_alloc_dtor(gest_collection *col,
size_t sz,
void (*free)(void*))
{
struct gest_entry *ent;
ent = malloc(sizeof(struct gest_entry));
ent->ptr = calloc(1, sz);
ent->free = free;
ent->prev = col->tail;
col->tail = ent;
col->nitems++;
return ent->ptr;
}
12.3.2. Memory allocation only
Much of the time the destructor is not needed, so a more
convenient collection_alloc
function is provided.
static void * collection_alloc(gest_collection *col, size_t sz);
Creates a new entry, allocates a void pointer, appends the entry to the list, then returns the pointer.
static void * collection_alloc(gest_collection *col, size_t sz)
{
return collection_alloc_dtor(col, sz, NULL);
}
12.3.3. Gesture Allocator Helper functions
The static function gest_alloc
is a helper function
which mostly exists to make code look cleaner.
static void * gest_alloc(gest_d *gest, size_t sz);
static void * gest_alloc(gest_d *gest, size_t sz)
{
return collection_alloc(&gest->col, sz);
}
12.4. Freeing The Collection
All previously allocated memory in Gest can be freed with
the function collection_cleanup
.
static void collection_cleanup(gest_collection *col);
Iterate through the linked list and free it all.
Note that the linked list moves backwards from the tail to the head so that the most recently allocated stuff gets freed first. This is done to minimize situations where allocated items are somehow required to exist before being freed.
static void collection_cleanup(gest_collection *col)
{
int n;
struct gest_entry *ent, *prev;
ent = col->tail;
for (n = 0; n < col->nitems; n++) {
prev = ent->prev;
if (ent->free != NULL) ent->free(ent->ptr);
free(ent->ptr);
free(ent);
ent = prev;
}
}
prev | home | next