NAME
xmalloc.h - smarter memory allocation
SYNOPSIS
This module provides memory allocation with automatic error checking. It also keeps track of the memory used by each allocated pointer and the total used for a process. It supports debugging with checks for valid frees and gives a summary of outstanding pointers.
#include <xalloc.h>
void *xmalloc(size_t sz);
void *xcalloc(size_t num, size_t sz);
void *xrealloc(void *ptr, size_t sz);
void *xrecalloc(void *ptr, size_t num, size_t sz);
void xfree(void *ptr);
void xcfree(void *ptr);
char *xstrdup(char *str);
size_t xmemsize(void *ptr);
size_t xmemused(void);
void xalloc_report(void);
void xalloc_shutdown(void);
DESCRIPTION
Must of the routines in xalloc(3) work identically To the corresponding routines in malloc(3) with some minor differences. The first difference is that failure to get memory is consider a fatal error for the xalloc(3) routines. If no memory is available ulog() is called with an appropriate message. Therefore, you never need to check for a NULL return value.
The second difference is that the xalloc(3) routines can keep track of the size of a pointer's memory on a pointer by pointer basis. Therefore, at any future time you can determine the size of any memory segment that was allocated with the xalloc(3) routines.
Note that you cannot mix calls between the xalloc(3) routines and the malloc(3) routines: if you get memory with xmalloc() it must be freed with xfree(), not free().
More extensive debugging features are summarized after this section.
Function Definitions
The following function prototypes are given in the header file xalloc.h.
void *xmalloc(size_t sz);
Allocates sz bytes and returns a pointer to the allocated memory. The memory is not cleared.
void *xcalloc(size_t num, size_t sz);
Allocates memory for an array of num elements with each element consisting of sz bytes and returns a pointer to the memory. The memory is cleared to zero.
void *xrealloc(void *ptr, size_t sz);
xrealloc() changes the size of the memory block pointed to by ptr to sz bytes. The contents will be unchanged to the minimum of the old and new sizes; newly allocated memory will be uninitialized. If ptr is NULL, the call is equivalent to xmalloc(sz); if sz is equal to zero, the call is equivalent to xfree(ptr). Unless ptr is NULL, it must have been returned by an earlier call to xmalloc(), xcalloc(), or xrealloc().
void *xrecalloc(void *ptr, size_t num, size_t sz);
xrecalloc() has no counterpart in the malloc(3) routines, yet the author swears that he has found a legitimate use for it. xrecalloc() behaves exactly like xrealloc() except the arguments num and sz have the same meaning as in xcalloc().
void xfree(void *ptr);
Frees the memory pointed to by ptr which must have been allocated by xmalloc() or xrealloc().
void xcfree(void *ptr);
Frees the memory pointed to by ptr which must have been allocated by xcalloc() or xrecalloc().
char *xstrdup(char *str);
Like strdup() but uses xmalloc().
size_t xmemsize(void *ptr);
Returns the number of bytes in the memory pointed to by ptr, which must have been returned by one of the above xalloc(3) routines. Due to some programming trickery, xmemsize() is a constant time operation, i.e. you can use it as often as you wish with almost no additional overhead.
size_t xmemused(void);
Returns the total number of outstanding bytes used by all of the memory returned by the xalloc(3) routines.
void xalloc_report(void);
This function gives a summary report of each outstanding pointer that has not been freed. Some sample output:
------------- total xmalloc() & xcalloc() : 512 total xrealloc() & xrecalloc() : 256 total xfree() & xcfree() : 1024
ID FILE LINE SOURCE ADDRESS SIZE -- ---- ---- ------ ------- ---- 278 foo.c 623 xmalloc 0x12345678 256 324 foo.c 627 xmalloc 0xabcd1234 256 745 bar.c 118 xrealloc 0x1234abcd 256
The summary states that there are three outstanding pointers. Most of the information is self explanatory; however, the ID field gives some indication as to when a pointer was originally allocated as id's are simply assigned by adding 1 to the last id assigned, with the first id being 0.
void xalloc_shutdown(void);
This routine does something only if you have been using the debugging xalloc(3) routines, in which case it will free up internal tables used to keep track of outstanding pointers.
Miscellaneous Items
The external int xalloc_fail_on_null is set to 1 by default, which means that all routines which return memory will fail with an appropriate error message and ultimately halt the program by calling xfatal(). You can prevent the halt by setting xalloc_fail_on_null to 0.
DEBUGGING ROUTINES
If you define XALLOC_DEBUG before you include xalloc.h then all of the routines will be aliased to debugging versions. Each pointer will be stored in a hash table which contains information such as the size, file, and line location of the calls. At any time you can call xalloc_report() to get a complete summary of all pointers. Moreover, the freeing and reallocating routines will check to make sure that the supplied pointers are valid.
Because most program source is divided into several files, and memory may be allocated in one file but deallocated in another, you should normally set XALLOC_DEBUG to either true or false for every source file in your program. Otherwise, you could potentially have a pointers allocated with a debugging routine but freed with a non-debugging routine. Don't do this.
AUTHOR
Gary William Flake (gary.flake@usa.net).
CREDITS
Credit for some implementation ideas goes to Chris Torek and Jos Horsmeier.
SEE ALSO
brk(2), malloc(3), ulog(3).