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
162
163
|
/* These are some dynamic memory allocation facilities. They are essentially
an extension to C, as they do allocations with a cognizance of C
variables. You can use them to make C read more like a high level
language.
Before including this, you must define an __inline__ macro if your
compiler doesn't recognize it as a keyword.
*/
#ifndef MALLOCVAR_INCLUDED
#define MALLOCVAR_INCLUDED
#include "pm_config.h"
#include <limits.h>
#include <stdlib.h>
#ifdef __cplusplus
extern "C" {
#endif
#if 0
} /* to fake out automatic code indenters */
#endif
static __inline__ void
mallocProduct(void ** const resultP,
size_t const factor1,
unsigned int const factor2) {
/*----------------------------------------------------------------------------
malloc a space whose size in bytes is the product of 'factor1' and
'factor2'. But if the malloc fails, or that size is too large even to
request from malloc, return NULL without allocating anything.
If either factor is zero, malloc a single byte.
-----------------------------------------------------------------------------*/
/* C99 introduces SIZE_MAX, the maximum size_t value.
Pre-C99, we do the best we can, assuming conventional encoding of
numbers and that size_t is unsigned.
*/
size_t const sizeMax =
#if defined(SIZE_MAX)
SIZE_MAX
#else
~((size_t)0)
#endif
;
if (factor1 == 0 || factor2 == 0)
*resultP = malloc(1);
else {
/* N.B. The type of malloc's argument is size_t */
if ((size_t)factor2 != factor2)
*resultP = NULL;
else {
if (sizeMax / factor2 < factor1)
*resultP = NULL;
else
*resultP = malloc(factor1 * factor2);
}
}
}
static __inline__ void
reallocProduct(void ** const blockP,
size_t const factor1,
unsigned int const factor2) {
size_t const sizeMax =
#if defined(SIZE_MAX)
SIZE_MAX
#else
~((size_t)0)
#endif
;
void * const oldBlockP = *blockP;
void * newBlockP;
/* N.B. The type of realloc's argument is size_t */
if ((size_t)factor2 != factor2)
newBlockP = NULL;
else {
if (sizeMax / factor2 < factor1)
newBlockP = NULL;
else
newBlockP = realloc(oldBlockP, factor1 * factor2);
}
if (newBlockP)
*blockP = newBlockP;
else {
free(oldBlockP);
*blockP = NULL;
}
}
#define MALLOCARRAY(arrayName, nElements) do { \
void * array; \
mallocProduct(&array, nElements, sizeof(arrayName[0])); \
arrayName = array; \
} while (0)
#define REALLOCARRAY(arrayName, nElements) do { \
void * array; \
array = arrayName; \
reallocProduct(&array, nElements, sizeof(arrayName[0])); \
if (!array && arrayName) \
free(arrayName); \
arrayName = array; \
} while (0)
#define MALLOCARRAY_NOFAIL(arrayName, nElements) \
do { \
MALLOCARRAY(arrayName, nElements); \
if ((arrayName) == NULL) \
abort(); \
} while(0)
#define REALLOCARRAY_NOFAIL(arrayName, nElements) \
do { \
REALLOCARRAY(arrayName, nElements); \
if ((arrayName) == NULL) \
abort(); \
} while(0)
#define MALLOCARRAY2(arrayName, nRows, nCols) do { \
void * array; \
pm_mallocarray2(&array, nRows, nCols, sizeof(arrayName[0][0])); \
arrayName = array; \
} while (0)
#define MALLOCARRAY2_NOFAIL(arrayName, nRows, nCols) do { \
MALLOCARRAY2(arrayName, nRows, nCols); \
if ((arrayName) == NULL) \
abort(); \
} while (0)
void
pm_freearray2(void ** const rowIndex);
#define MALLOCVAR(varName) \
varName = malloc(sizeof(*varName))
#define MALLOCVAR_NOFAIL(varName) \
do {if ((varName = malloc(sizeof(*varName))) == NULL) abort();} while(0)
void
pm_mallocarray2(void ** const resultP,
unsigned int const cols,
unsigned int const rows,
unsigned int const elementSize);
#ifdef __cplusplus
}
#endif
#endif
|