From 7e0f021a9aec35fd8e6725e87e3313b101d26f5e Mon Sep 17 00:00:00 2001 From: Tobias Klauser Date: Sun, 27 Jan 2008 11:37:44 +0100 Subject: Initial import (2.0.2-6) --- reference/C/CONTRIB/SNIP/mdalloc.c | 160 +++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100755 reference/C/CONTRIB/SNIP/mdalloc.c (limited to 'reference/C/CONTRIB/SNIP/mdalloc.c') diff --git a/reference/C/CONTRIB/SNIP/mdalloc.c b/reference/C/CONTRIB/SNIP/mdalloc.c new file mode 100755 index 0000000..171d464 --- /dev/null +++ b/reference/C/CONTRIB/SNIP/mdalloc.c @@ -0,0 +1,160 @@ +/* Written by Blair Haukedal 91/09 and placed in the public domain */ + +/* mdalloc - a multi dimensional array allocator + * mdfree - a companion function to mdalloc for freeing storage + * synopsis: + * void *mdalloc(int ndim, int width, ...); + * where: ndim: number of array dimensions + * width: size of elements in array + * variable args are dimensions of array + * returns: n-way indirect pointer to allocated storage + * or NULL if insufficient storage + * + * void mdfree(void *p, ndim); + * where: p: pointer to storage obtained by mdalloc + * ndim: number of dimensions used in mdalloc + * + * example: + * int ***tip; + * tip = mdalloc(3, sizeof(int), 2, 3, 4); + * tip will be a triple indirect pointer to a 3 dimensional array + * tip[0][0][0] refers to the first int in a contiguous area of + * storage that is 2*3*4*sizeof(int) bytes long + * tip[0][0] is the address of the first int + * memset can be used to initialize array elements as follows: + * memset(tip[0][0], 0, 2*3*4*sizeof(int)); + * mdfree is used to free storage obtained with mdalloc: + * mdfree(tip, 3) + * + * notes: + * - must be compiled with appropriate memory model + * - memory is allocated for each dimension for indirect pointers + * eg. 3x4x5 array of longs + * (assuming 4 byte longs, small mem model) + * p = mdalloc(3, sizeof(long), 3, 4, 5) - bytes + * 3 pointers allocated for 1st dimension - 6 + * 3x4 pointers allocated for 2nd dimension - 24 + * 3x4x5 longs allocated for array elements - 240 + * total of 270 bytes allocated + * - if insufficient memory, nothing will be allocated. + * ie. intermediate pointer arrays that were successfully + * allocated will be freed. + * - the intent of mdalloc is to facilitate dynamic array creation, + * it will use more memory than statically declared arrays, and + * the required dereferencing will be slower than the use of + * statically declared arrays. + * - this function assumes that sizeof(char) == 1. + */ + +#include +#include + +static void **md2(int n_units, int ndim, int *dims); +static void md3(char ***tip, int n_units, int ndim, int *dims); + +static int w_units; + +/* mdalloc: entry point for mdalloc function described above + * - reduces variable arg list to fixed list with last arg + * represented as pointer to int (array dimensions). + * Calls md2 to allocate storage. + * Calls md3 to initialize intermediate pointers. + * Returns pointer. + */ + +void *mdalloc(int ndim, int width, ...) +{ + va_list argp; + int *dims, i; + char ***tip; + + va_start(argp, width); + + /* allocate storage for variable args (dimensions) */ + + dims = malloc(ndim*sizeof(int)); + if(dims == NULL) + return NULL; + + /* initialize dimensions array for subsequent calls */ + + for(i=0; i1 && tip) + md3(tip, dims[0], ndim-1, &dims[1]); /* init pointers */ + + free(dims); + return tip; +} + +/* mdfree: companion function to mdalloc + * frees storage obtained by mdalloc + */ + +void mdfree(void *tip, int ndim) +{ + if(ndim == 1) + free(tip); + else + { + mdfree(((void **)tip)[0], ndim-1); + free(tip); + } +} + +/* md2: allocates storage for n-way indirect pointer arrays + * allocates storage for requested array elements + */ + +static void **md2(int n_units, int ndim, int *dims) +{ + char **tip; + + if(ndim == 1) + /* recursed to final dimension - allocate element storage */ + tip = malloc(n_units*w_units); + else + { + /* allocate pointer array for dimension n */ + tip = malloc(n_units*sizeof(char *)); + if(tip) + { + /* recurse until final dimension */ + tip[0] = (char *)md2(n_units*dims[0], ndim-1, &dims[1]); + if(tip[0] == NULL) + { + /* allocate error - fall back up freeing everything */ + free(tip); + tip = NULL; + } + } + } + return (void **)tip; +} + +/* md3: initializes indirect pointer arrays */ + +static void md3(char ***tip, int n_units, int ndim, int *dims) +{ + int i; + + for(i=1; i 1) + /* not at final dimension - continue to recurse */ + md3((char ***)tip[0], n_units*dims[0], ndim-1, &dims[1]); +} -- cgit v1.2.3-54-g00ecf