1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
|
/*
AMALLOC - multi-dimensional malloc()
Allocates a multidimensional array dynamically, at runtime, so that
1: its elements can be accessed using multiple indirection
2: it can be deallocated using a call to the standard free() function
Note: On PC's the max array size is 64K
Paul Schlyter, 1992-02-09. Released to the public domain.
*/
#include <stdlib.h>
#include <stdarg.h>
#include <string.h>
#define MAXDIMS 5 /* Defines the maximum number of dimensions */
#define MAXSIZE ((size_t) -1L) /* Maximum size of array */
void *amalloc( int esiz, void *initval, int dims, ... )
/*
* Input: esiz size of each array elements, as given by sizeof
* initval pointer to initial value. NULL ==> zero fill
* dims number of dimensions: 1..MAXDIMS (5)
* ... number of elements in each dimension (int's)
*
* Returns: NULL error: out of memory, or illegal parameters
* otherwise base pointer to array
*/
{
unsigned int dim[MAXDIMS], accdim[MAXDIMS];
va_list ap;
int i, j;
long int totsiz;
void **q;
char *p, *r, *s;
if (dims < 1 || dims > MAXDIMS)
return NULL;
memset(dim, 0, sizeof(dim)); /* Read dimension numbers */
memset(accdim, 0, sizeof(accdim));
va_start(ap, dims);
dim[0] = accdim[0] = va_arg(ap,int);
for (i = 1; i < dims; i++)
{
dim[i] = va_arg(ap,int);
accdim[i] = accdim[i-1] * dim[i];
}
va_end(ap);
/* Compute total array size */
totsiz = esiz * accdim[dims-1]; /* Data size */
for (i = 0; i < dims - 1; i++ ) /* Add space for pointers */
totsiz += sizeof(void *) * accdim[i];
if (totsiz > MAXSIZE) /* Exit if totsiz too large */
return NULL;
p = malloc((size_t) totsiz); /* Allocate memory */
if (p == NULL) /* Out-of-memory */
return NULL;
memset(p, 0, (unsigned int) totsiz); /* Zero out allocated memory */
q = (void **) p;
if (dims == 1)
r = (char *) q + esiz * accdim[0];
for (i = 1; i < dims; i++) /* Fill in pointers */
{
int siz;
int accd = accdim[i-1], d = dim[i];
siz = i == dims-1 ? esiz : sizeof(void *);
r = (char *) q + sizeof(void *) * accd;
for (j = 0; j < accd; j++)
{
*q++ = r;
r += siz * d;
}
}
if (initval != NULL)
{
for (s = (char *) q; s < r; s += esiz)
memcpy(s, initval, esiz);
}
return p;
} /* amalloc */
#ifdef TEST /* Test program */
#include <stdio.h>
main()
{
static char init_d[8] = { 0x01,0x23,0x45,0x67,0x89,0xAB,0xCD,0xEF };
int init_i = 0x1111;
double *a = amalloc( sizeof(double), init_d, 1, 4 );
double **b = amalloc( sizeof(double), init_d, 2, 4, 5 );
double ***c = amalloc( sizeof(double), init_d, 3, 4, 5, 6 );
int ***d = amalloc( sizeof(int), &init_i, 3, 4, 5, 6 );
int i, j, k;
for (i = 0; i < 4; i++)
for (j = 0; j < 5; j++ )
for (k = 0; k < 6; k++ )
d[i][j][k] = (i * 256) + (j * 16) + k;
a = a, b = b, c = c;
return 0;
}
#endif
|