/**************************************************************************************** * Calloc4d.c * * WRITTEN BY DANIEL GOTTAS OF THE METEOROLOGICAL APPLICATIONS * * AND ASSESSMENT DIVISION OF NOAA'S ENVIRONMENTAL TECHNOLOGY LAB * * (released on 3/6/95) * * * * Dynamic_array dynamically allocates memory for multidimensional arrays (of 1-4 * * dimensions) containing any data type. This function is written in ANSI C and * * is therefore compatible with both UNIX and DOS platforms. * * * * If used within the DOS environment, the cummulative size of all elements within * * an array is limited to 64K. In addition, no more than 640K of memory may be used * * during a DOS session which thereby limits the amount of memory available for * * multiple array allocation. To break the 640K barrier, this program may be * * used with DOS extenders, in particular it has been tested with success using * * Phar Lap's 286/DOS-Extender Kit (PLDEK). To break the 64K segment barrier, use * * the huge_dynamic_array function (also released on 3/6/95). * * * * IT IS THE LEAGAL RESPONSIBILITY OF THE USER TO OBTAIN A LICENSED COPY OF PLDEK * * OR ANY OTHER DOS EXTENDER WHEN USED IN CONJUNCTION WITH THIS PROGRAM. * * * * -----------***************------------ * * * * INCLUDE: * * #include "array4d.h" * * SYNTAX: * * void * dynamic_array(size_t DIM1,size_t DIM2,size_t DIM3,size_t DIM4, * * size_t DATA_SIZE,size_t POINTER_SIZE) * * INPUT: * * DIM1 = number of elements in the 1st dimension of the array * * DIM2 = number of elements in the 2nd dimension of the array * * DIM3 = number of elements in the 3rd dimension of the array * * DIM4 = number of elements in the 4th dimension of the array * * DATA_SIZE = length in bytes of the data stored in each element * * POINTER_SIZE = length in bytes of each pointer (pointing to * * the data in each element) * * OUTPUT: * * The dynamic_array function returns a pointer to the allocated space. * * To get a pointer to a type other than void, use a type cast on the * * return value. * * USAGE: * * Equate dynamic_array to a multiple pointer determined by the * * number of dimensions desired in array notation. For example, to * * allocate memory for the 3D floating point array data[i][j][k], * * first define "float ***data" in the main program. To allocate * * memory to data, call dynamic_array as follows: * * "data=(float ***)dynamic_array(i,j,k,0,sizeof(float),sizeof(float *))"* * Array elements may then be accessed using array or pointer notation, * * for example data[i][j][k] or *(*(*(data+i)+j)+k). * * * * * * FUNCTIONS USED: * * * * check_dims: Checks if the specified array dimensions are in the proper * * order. If an error is detected, the function outputs a * * message to the screen, does not allocate the requested * * memory and returns a NULL pointer to the user through * * dynamic_array. * * * * alloc_1d: Dynamically allocates memory to voided single pointers * * using the calloc function. The function outputs a memory * * error message to the screen when calloc fails and returns a * * NULL pointer to the user through dynamic_array. * * * * alloc_2d: Dynamically allocates memory to voided double pointers * * using the same features as alloc_1d. * * * * alloc_3d: Dynamically allocates memory to voided triple pointers * * using the same features as alloc_1d. * * * * alloc_4d: Dynamically allocates memory to voided quadruple * * pointers using the same features as alloc_1d. * * * * memory_error: Prints a memory error to the screen when called by the * * alloc functions. * * * ****************************************************************************************/ #include "array4d.h" /**************************************************************************/ void * dynamic_array(size_t i,size_t j,size_t k,size_t l,size_t d_size, size_t p_size) { int dim_cnt=0; union p_vars point; if(!(dim_cnt=check_dims(i,j,k,l))) return(NULL); // obtain the # of dimensions switch ((dim_cnt)) // allocate memory according to the number of dimensions specified { case(1): // 1D case { point.dim1=(void *)alloc_1d(i,d_size); return(point.dim1); } case(2): // 2D case { point.dim2=(void **)alloc_2d(i,j,p_size,d_size); return(point.dim2); } case(3): // 3D case { point.dim3=(void ***)alloc_3d(i,j,k,p_size,d_size); return(point.dim3); } case(4): // 4D case { point.dim4=(void ****)alloc_4d(i,j,k,l,p_size,d_size); return(point.dim4); } } } /************************************************************************/ void * alloc_1d(size_t i,size_t d_size) { void *point1; /* allocate memory for 1st dimension pointers */ point1=(void *)calloc(i,d_size); if(point1==NULL) { memory_error(); return(NULL); } return(point1); } /************************************************************************/ void * alloc_2d(size_t i,size_t j,size_t p_size,size_t d_size) { void **point2; size_t x; /* allocate memory for 1st dimension pointers */ point2=(void **)calloc(i,p_size); if(point2==NULL) { memory_error(); return(NULL); } /* allocate memory for 2nd dimension pointers */ for(x=0;x