diff --git a/common/common-helpers.c b/common/common-helpers.c index 5cffc82..cfbdd36 100644 --- a/common/common-helpers.c +++ b/common/common-helpers.c @@ -39,3 +39,4 @@ POSSIBILITY OF SUCH DAMAGE. * a specific call to the function the linker will expect an definition. */ extern inline void cleanup_close(int *fd); +extern inline void cleanup_free(void *ptr); diff --git a/common/common-helpers.h b/common/common-helpers.h index 6af4ba2..d079b3f 100644 --- a/common/common-helpers.h +++ b/common/common-helpers.h @@ -31,6 +31,7 @@ POSSIBILITY OF SUCH DAMAGE. #pragma once +#include #include #include #include @@ -80,3 +81,23 @@ inline void cleanup_close(int *fd_ptr) * like "autoclose_fd int fd = -1;". */ #define autoclose_fd __attribute__((cleanup(cleanup_close))) + +/** + * Helper function for auto-freeing dynamically allocated memory. Does nothing + * if *ptr is NULL (ptr must not be NULL). + */ +inline void cleanup_free(void *ptr) +{ + /* The function is defined to work with 'void *' because + * that will make sure it compiles without warning also + * for all types; what we are getting passed into is a + * pointer to a pointer though, so we need to cast */ + void *target = *(void **)ptr; + free(target); /* free can deal with NULL */ +} + +/** + * Helper macro for auto-freeing dynamically allocated memory: use by + * prefixing the variable, like "autofree char *data = NULL;". + */ +#define autofree __attribute__((cleanup(cleanup_free)))