/
allocate.c
163 lines (131 loc) · 5.02 KB
/
allocate.c
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
#include <stdio.h>
#include <stdlib.h>
#include <stdarg.h>
#include "allocate.h"
void *get_spc(size_t num, size_t size)
{
void *pt;
if( (pt=calloc(num,size)) == NULL ) {
fprintf(stderr, "get_spc(): calloc() error\n");
exit(-1);
}
return(pt);
}
void *mget_spc(size_t num, size_t size)
{
void *pt;
if( (pt=malloc(num*size)) == NULL ) {
fprintf(stderr, "mget_spc(): malloc() error\n");
exit(-1);
}
return(pt);
}
void **get_img(size_t wd,size_t ht,size_t size)
{
size_t i;
void **ppt;
char *pt;
ppt = (void **)mget_spc(ht,sizeof(void *));
pt = (char *)mget_spc(wd*ht,size);
for(i=0; i<ht; i++) ppt[i] = pt + i*wd*size;
return(ppt);
}
void free_img(void **pt)
{
free( (void *)pt[0]);
free( (void *)pt);
}
/* modified from dynamem.c on 4/29/91 C. Bouman */
/* Converted to ANSI on 7/13/93 C. Bouman */
/* Modified for 1-D case on 6/29/95 C. Bouman */
/* Modified for 64 bit memory allocation 8/29/2013 A. Mohan */
/* multialloc( s, d, d1, d2 ....) allocates a d dimensional array, whose */
/* dimensions are stored in a list starting at d1. Each array element is */
/* of size s. */
void *multialloc(size_t s, int d, ...)
{
va_list ap; /* varargs list traverser */
size_t max; /* size of array to be declared */
size_t j; /* loop counter */
size_t *d1,*q; /* pointer to dimension list */
char **r; /* pointer to beginning of the array of the
* pointers for a dimension */
char **s1, *t, *tree; /* base pointer to beginning of first array */
int i; /* loop counter */
if(d<1) {
fprintf(stderr, "multialloc() error: Number of array dimensions is not positive.\n");
exit(-1);
}
va_start(ap,d);
d1 = (size_t *) mget_spc(d,sizeof(size_t));
for(i=0;i<d;i++)
d1[i] = (size_t) va_arg(ap,int);
/* Take care of 1-D case separately (6/29/95) */
if( d==1 ) {
tree = (char *)mget_spc(d1[0],s*sizeof(char));
free((void *)d1);
return((void *)tree); /* return base pointer */
}
r = &tree;
q = d1; /* first dimension */
max = 1;
for (i = 0; i < d - 1; i++, q++) { /* for each of the dimensions
* but the last */
max *= (*q);
r[0]=(char *)mget_spc(max,sizeof(char **));
r = (char **) r[0]; /* step through to beginning of next
* dimension array */
}
max *= s * (*q); /* grab actual array memory */
r[0] = (char *)mget_spc(max,sizeof(char));
/*
* r is now set to posize_t to the beginning of each array so that we can
* use it to scan down each array rather than having to go across and
* then down
*/
r = (char **) tree; /* back to the beginning of list of arrays */
q = d1; /* back to the first dimension */
max = 1;
for (i = 0; i < d - 2; i++, q++) { /* we deal with the last
* array of pointers later on */
max *= (*q); /* number of elements in this dimension */
for (j=1, s1=r+1, t=r[0]; j<max; j++) { /* scans down array for
* first and subsequent
* elements */
/* modify each of the pointers so that it points to
* the correct position (sub-array) of the next
* dimension array. s1 is the current position in the
* current array. t is the current position in the
* next array. t is incremented before s1 is, but it
* starts off one behind. *(q+1) is the dimension of
* the next array. */
*s1 = (t += sizeof (char **) * *(q + 1));
s1++;
}
r = (char **) r[0]; /* step through to begining of next
* dimension array */
}
max *= (*q); /* max is total number of elements in the
* last pointer array */
/* same as previous loop, but different size factor */
for (j = 1, s1 = r + 1, t = r[0]; j < max; j++)
*s1++ = (t += s * *(q + 1));
va_end(ap);
free((void *)d1);
return((void *)tree); /* return base pointer */
}
/*
* multifree releases all memory that we have already declared analogous to
* free() when using malloc()
*/
void multifree(void *r, int d)
{
void **p;
void *next=NULL;
int i;
for (p = (void **)r, i = 0; i < d; p = (void **) next,i++)
if (p != NULL) {
next = *p;
free((void *)p);
}
}