9.2.1.2 Memory Management

back: error management
forward: generalised list data type
 
fastback: generalised list data type
up: portability infrastructure
fastforward: library implementation
top: autoconf, automake, and libtool
contents: table of contents
index: index
about: about this document

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.


This document was generated by Gary V. Vaughan on May, 24 2001 using texi2html


GNU Autoconf, Automake and Libtool
GNU Autoconf, Automake, and Libtool
ISBN: 1578701902
EAN: 2147483647
Year: 2002
Pages: 290

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net