libtalloc_destructors(3)

πŸ“¦
version 2.4.4 Β· 2 versions
, in centos-stream 10, fedora 43, fedora 44, opensuse-leap 16.0

✨ NAME ✨

ok so this is libtalloc_destructors β€” the page for Chapter 4: Using destructors πŸ’– it's part of the libtalloc manual, and it's literally about making C do the cute object-oriented thing where stuff cleans up after itself 🫢


πŸŽ€ Using destructors πŸŽ€

ok bestie, so destructors are like super well known in the object oriented programming world πŸ’… a destructor is a method of an object that gets automatically run when the object is destroyed. and what's it for? giving resources back to the system that the object took β€” like closing file descriptors, terminating a connection to a database, deallocating memory 🌸 basically it's the object's little goodbye routine.

and the way that talloc lets us have destructors even in C?? iconic. no cap. we can easily attach our very own destructor to a talloc context, and when the context is freed, the destructor runs automatically ✨

to attach/detach a destructor to a talloc context, use:

talloc_set_destructor();

🌈 Example 🌈

picture this: we have a dynamically created linked list πŸ¦‹ before we deallocate an element of the list, we need to make sure we've successfully removed it from the list first. normally that's two separate commands in the exact order β€” remove it from the list, then free the element. but with talloc? we can do it all at once by setting a destructor on the element that removes it from the list, and then talloc_free() does the rest 😌 main character energy fr.

so the destructor would be:

int list_remove(void *ctx)
{
    struct list_el *el = NULL;
    el = talloc_get_type_abort(ctx, struct list_el);
    /* remove element from the list */
}

now β€” GCC version 3 and newer can check for the types during compilation πŸ‘€ so if that's our major compiler, we can use a more advanced destructor:

int list_remove(struct list_el *el)
{
    /* remove element from the list */
}

next up, we assign the destructor to the list element πŸ’œ and we can do that directly in the function that inserts it:

struct list_el* list_insert(TALLOC_CTX *mem_ctx,
                            struct list_el *where,
                            void *ptr)
{
  struct list_el *el = talloc(mem_ctx, struct list_el);
  el->data = ptr;
  /* insert into list */

  talloc_set_destructor(el, list_remove);
  return el;
}

and because talloc is a hierarchical memory allocator, we can go a step further and free the data along with the element too πŸ”₯

struct list_el* list_insert_free(TALLOC_CTX *mem_ctx,
                                 struct list_el *where,
                                 void *ptr)
{
  struct list_el *el = NULL;
  el = list_insert(mem_ctx, where, ptr);

  talloc_steal(el, ptr);

  return el;
}

and that's the whole page bestie, you ate that πŸ’…βœ¨

this was libtalloc_destructors(3) from the Library Functions Manual, talloc Version 2.0 era πŸŽ€ sending u love, go free ur contexts responsibly πŸ«ΆπŸ’–