-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathallocate.c
150 lines (120 loc) · 4.49 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
/* allocate.c */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include "stdafx.h"
#include "allocate.h"
void *get_spc(int num, size_t size)
{
void *pt;
if( (pt=calloc((size_t)num,size)) == NULL ) {
fprintf(stderr, "==> calloc() error\n");
exit(-1);
}
return(pt);
}
void *mget_spc(int num,size_t size)
{
void *pt;
if( (pt=malloc((size_t)(num*size))) == NULL ) {
fprintf(stderr, "==> malloc() error\n");
exit(-1);
}
return(pt);
}
void **get_img(int wd,int ht,size_t size)
{
void *pt;
if( (pt=multialloc(size,2,ht,wd))==NULL) {
fprintf(stderr, "get_img: out of memory\n");
exit(-1);
}
return((void **)pt);
}
void free_img(void **pt)
{
multifree((void *)pt,2);
}
/* modified from dynamem.c on 4/29/91 C. Bouman */
/* Converted to ANSI on 7/13/93 C. Bouman */
/* 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 */
int max, /* size of array to be declared */
*q; /* pointer to dimension list */
char **r, /* pointer to beginning of the array of the
* pointers for a dimension */
**s1, *t, *tree; /* base pointer to beginning of first array */
int i, j; /* loop counters */
int *d1; /* dimension list */
va_start(ap,d);
d1 = (int *) mget_spc(d,sizeof(int));
for(i=0;i<d;i++)
d1[i] = va_arg(ap,int);
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 point 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;
int i;
for (p = (void **)r, i = 0; i < d; p = (void **) next,i++)
if (p != NULL) {
next = *p;
free((void *)p);
}
}