memchunk(3S) C_MEMORY_FUNCTIONS memchunk(3S) NAME Memory allocation package with error checking. SYNOPSIS #include "memchunk.h" cc -o ... -lV.a MEMP GetChunk(n,dsc) MEMS n; char* dsc; MEMP GetAChunk(n,a,dsc) MEMS n; int a; char* dsc; int RelChunk(p,dsc) MEMP p; char* dsc; int IRelChunk(p,dsc) MEMP p; char* dsc; int FreeChunk(p,n,dsc) MEMP p; MEMS n; char* dsc; int SizChunk(p,m,n,dsc) MEMP p; MEMS m, n; char* dsc; int ChkChunk(p,dsc) MEMP p; char* dsc; void DmpChunk(p,dsc) MEMP p; char* dsc; void DmpChunkList() MEMS memalign; /* Memory alignment size */ ALSO NEEDED Some version of the standard Unix malloc library. DESCRIPTION This is a memory-allocation package that is designed to sit on top of the malloc package (or any similar package that knows how to allocate and free arbitrary-sized chunks of memory). It keeps its own list of free and allocated chunks, and is capable of doing various sorts of debugging checks. Note that the functions listed in the SYNOPSIS section are all macros, and you MUST include memchunk.h for this package to work. You will also need to link to the V library, which is heavily used by the memchunk package to produce diagnostics. All the routines in the memchunk package take an extra argument dsc which should be a printable string describing the chunk. It will be used in diagnostic messages to help identify the block involved. FUNCTIONS The memchunk routines are functionally equivalent to things in the malloc library, and you can convert via the substitutions: malloc(n) ==> GetChunk(n,dsc) free(p) ==> RelChunk(p,dsc) realloc(p,m,n) ==> SizChunk(p,m,n,dsc) GetAChunk(n,a,dsc) gets a chunk which is aligned on an address that is a multiple of a. The size will also be incremented to the next multiple of a, if it isn't already. If no more memory is available, the return value is null and errno is set to ENOMEM. GetChunk(n,dsc) allocates a chunk of (at least) n bytes and returns its address. This function is actually a macro, defined as GetAChunk(n,memalign,dsc), which will produce alignment to a multiple of 8 or 16 bytes on most machines. RelChunk(p,dsc) releases a chunk to the free list. The value of p must be a chunk returned by GetChunk. The return value is the size of p. Failure (which means that p isn't an allocated chunk) results in a return value of zero, with errno = EINVAL. IRelChunk(p,dsc) is like RelChunk(p,dsc), except: 1) p is checked to make sure it is nonnull; 2) p is set to null. This simplifies the code when you aren't sure whether p is allocated, and by setting p to null, helps ensure that the program won't try to use the chunk after freeing it. FreeChunk(p,n,dsc) releases a chunk of n bytes, starting at p. The chunk being freed need not be an allocated chunk. In fact, you may use FreeChunk() to free arbitrary global data. It will be added to the free-space list in the memchunk package. It is not returned to the malloc package via free(). If it is adjacent to another free chunk, they will be merged, so that the resulting larger chunk may be used later to satisfy larger GetChunk() requests. Note that attempting to free memory that overlaps an allocated chunk will produce a diagnostic message, and will be ignored. ChkChunk(p,dsc) does a set of validity tests on p. If p points to an allocated chunk, the return value will be zero; otherwise the return value is the number of errors detected (which is usually only 1, but may be more); errno is set to indicate the problem: EFAULT p is an unallocated chunk. EINVAL p is inside but isn't the address of a chunk. ENOMEM p is outside all chunks. WARNINGS If you convert calls of malloc() to calls of GetChunk(), you MUST also convert the corresponding calls of free() to calls of RelChunk() or FreeChunk(). If you call free() for a block obtained from GetChunk(), memchunk's list will still point to the chunk, and this can cause many problems. But note that it is safe to link together code that calls memchunk with code that calls malloc, as long as the two sets of memory blocks are kept separate and released via the appropriate routines. If you use FreeChunk(p,n,dsc) where p is a chunk obtained via GetChunk(m), and n is less that the entire chunk, the chunk will be split into two chunks, and the memchunk routines will assume that the remaining bytes are still in use. Since GetChunk(m) may have allocated a block of more than m bytes (up to the next multiple of memalign), this may not be the desired behavior. If you wish to free an entire chunk, it is generally better to use RelChunk(), which will determine the size for you. BUGS Hmmm...; there's gotta be some .... DEBUGGING John Chambers' audit/debug/verbose package is also used by this memory package, and V.h is #included by memchunk.h, so you don't need to #include it yourself, though it doesn't hurt if you do. This means that you must use -lV.a (or -laudit.a or -lverbose.a) when you use this string package. The DmpChunk() routine produces a dump (on the Vout stream) of what is known about a specific chunk; the DmpChunkList macro invokes a routine that dumps the info on all the chunks in the list (both in-use and free). The latter can produce a lot of output, of course. If you have used the "M" versions of the routines, the dump will show the (first 16 bytes of) descriptions of each block; this can help a lot in diagnosing memory leaks. AUTHOR John Chambers SEE ALSO malloc(3)