| A useful idiom common to many GNU projects is to wrap the memory management functions to localise out of memory handling , naming them with an `x' prefix. By doing this, the rest of the project is relieved of having to remember to check for `NULL' returns from the various memory functions. These wrappers use the error API to report memory exhaustion and abort the program. I have placed the implementation code in `xmalloc.c' : | #if HAVE_CONFIG_H # include <sic/config.h> #endif #include "common.h" #include "error.h" void * xmalloc (size_t num) { void *new = malloc (num); if (!new) sic_fatal ("Memory exhausted"); return new; } void * xrealloc (void *p, size_t num) { void *new; if (!p) return xmalloc (num); new = realloc (p, num); if (!new) sic_fatal ("Memory exhausted"); return new; } void * xcalloc (size_t num, size_t size) { void *new = xmalloc (num * size); bzero (new, num * size); return new; } | Notice in the code above, that xcalloc is implemented in terms of xmalloc , since calloc itself is not available in some older C libraries. Also, the bzero function is actually deprecated in favour of memset in modern C libraries -- I'll explain how to take this into account later in 9.2.3 Beginnings of a `configure.in' . Rather than create a separate `xmalloc.h' file, which would need to be #include d from almost everywhere else, the logical place to declare these functions is in `common.h' , since the wrappers will be called from most everywhere else in the code: | #ifdef __cplusplus # define BEGIN_C_DECLS extern "C" { # define END_C_DECLS } #else # define BEGIN_C_DECLS # define END_C_DECLS #endif #define XCALLOC(type, num) \ ((type *) xcalloc ((num), sizeof(type))) #define XMALLOC(type, num) \ ((type *) xmalloc ((num) * sizeof(type))) #define XREALLOC(type, p, num) \ ((type *) xrealloc ((p), (num) * sizeof(type))) #define XFREE(stale) do { \ if (stale) { free (stale); stale = 0; } \ } while (0) BEGIN_C_DECLS extern void *xcalloc (size_t num, size_t size); extern void *xmalloc (size_t num); extern void *xrealloc (void *p, size_t num); extern char *xstrdup (const char *string); extern char *xstrerror (int errnum); END_C_DECLS | By using the macros defined here, allocating and freeing heap memory is reduced from: | char **argv = (char **) xmalloc (sizeof (char *) * 3); do_stuff (argv); if (argv) free (argv); | to the simpler and more readable: | char **argv = XMALLOC (char *, 3); do_stuff (argv); XFREE (argv); | In the same spirit, I have borrowed `xstrdup.c' and `xstrerror.c' from project GNU's libiberty. See section 9.1.5 Fallback Function Implementations. |