File: memalloc.c

package info (click to toggle)
rel 1.3-3
  • links: PTS
  • area: non-free
  • in suites: hamm, potato, slink
  • size: 496 kB
  • ctags: 216
  • sloc: ansic: 1,868; sh: 254; makefile: 142
file content (220 lines) | stat: -rw-r--r-- 5,528 bytes parent folder | download
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
/*

------------------------------------------------------------------------------

A license is hereby granted to reproduce this software source code and
to create executable versions from this source code for personal,
non-commercial use.  The copyright notice included with the software
must be maintained in all copies produced.

THIS PROGRAM IS PROVIDED "AS IS". THE AUTHOR PROVIDES NO WARRANTIES
WHATSOEVER, EXPRESSED OR IMPLIED, INCLUDING WARRANTIES OF
MERCHANTABILITY, TITLE, OR FITNESS FOR ANY PARTICULAR PURPOSE.  THE
AUTHOR DOES NOT WARRANT THAT USE OF THIS PROGRAM DOES NOT INFRINGE THE
INTELLECTUAL PROPERTY RIGHTS OF ANY THIRD PARTY IN ANY COUNTRY.

Copyright (c) 1995, John Conover, All Rights Reserved.

Comments and/or bug reports should be addressed to:

    john@johncon.com (John Conover)

------------------------------------------------------------------------------

memalloc.c, memory allocation

void *memalloc (size_t size);

    allocate memory area of size, size, and include a reference to the
    allocated area in the allocated list

    the objective of this allocation routine is to provide a "memory
    shutdown" procedure in applications where many allocations are
    performed, but there are no deallocations until the program
    exits. These are typical requirements of parsing and numerical
    method applications. The advantage is that the memory can be
    deallocated on command, without maintaining tables of references
    to allocated areas. Of particular applicability are client/server
    architectures, where memory must be deallocated, without the
    program exiting, and memory leaks are to be avoided. The routine
    maintains a list, or stack, of elements that reference the
    allocated areas-permitting cycling through the list and freeing
    all allocated areas.

The algorithm is as follows:

    allocate a MEM element

    allocate the memory area

    push the MEM element on the allocated list

Usage is a call with the desired memory area size, for example:

    if ((my_ref = memalloc (size)) == (NULL) 0)
    {
        allocation_error ();
    }

The argument, size, is the size of the area to allocate.

Returns a reference to the allocated area, null if the area could not
be allocated.

$Revision: 1.0 $
$Date: 1995/04/22 05:13:18 $
$Id: memalloc.c,v 1.0 1995/04/22 05:13:18 john Exp $
$Log: memalloc.c,v $
 * Revision 1.0  1995/04/22  05:13:18  john
 * Initial revision
 *

*/

#include "rel.h"

#ifndef LINT /* include rcsid only if not running lint */

static char rcsid[] = "$Id: memalloc.c,v 1.0 1995/04/22 05:13:18 john Exp $"; /* module version */
static char rcsid_h[] = MEMALLOC_H_ID; /* module include version */

#endif

typedef struct mem
{
    void *reference; /* reference to allocated area */
    struct mem *next; /* reference to next element in the allocated list */
} MEM;

static MEM *mem_stack = (MEM *) 0; /* reference to the allocated list */

#ifdef __STDC__

void *memalloc (size_t size)

#else

void *memalloc (size)
    size_t size;

#endif

{
    void *retval = (void *) 0; /* return value, assume error */

    MEM *ref; /* reference to allocated list element */

    if ((ref = (MEM *) malloc (sizeof (MEM))) != (MEM *) 0) /* allocate the allocated list element, fall through if failure */
    {

        if ((retval = ref->reference = (void *) malloc (size)) != (void *) 0) /* allocate the area */
        {
            PUSH (mem_stack, ref); /* yes, push the token on the reverse postfix stack */
        }

        else
        {
            free ((void *) ref); /* couldn't allocate the area, free the allocated list element */
        }

    }

    return (retval); /* return aq reference to the allocated area */
}


/*

void memdealloc (void);

since memalloc() could be interrupted, a shutdown procedure is
necessary to deallocate memory-this routine should be installed as
part of the interrupt handling process, or prior to the exit of the
program

The algorithm is as follows:

    while there are elements on the allocated list

       pop the element from the allocated list

       free the allocated area referenced by the element

       free the element

There are no arguments, and no return value from this function

*/

#ifdef __STDC__

void memdealloc (void)

#else

void memdealloc ()

#endif

{
    MEM *ref; /* reference to allocated list element */

    while (mem_stack != (MEM *) 0) /* for each element in the allocated list */
    {
        ref = POP (mem_stack); /* pop the element off the allocated list */

        if (ref->reference != 0) /* area allocated? */
        {
            free ((void *) ref->reference); /* yes, deallocate the area allocated */
        }

        free ((void *) ref); /* deallocate the list element's  memory */
    }

}

#ifdef TEST_MEMALLOC

/*

simple exerciser for testing memalloc (); get a string from stdin,
convert it to ascii, and allocate an area of that size; ignore the:

declared global, could be static
    memalloc            memalloc.c(xxx)
    memdealloc          memalloc.c(yyy)

from lint

*/

#ifdef __STDC__

int main (void)

#else

int main ()

#endif

{
    char buffer[BUFSIZ]; /* buffer to be parsed */

    while (gets (buffer) != 0) /* input the size to be allocated */
    {
        (void) memalloc (atoi (buffer)); /* allocate the area */
    }

    memdealloc (); /* deallocate memory */
    exit (0); /* return any errors */

#ifdef LINT /* include only if running lint */

    return (0); /* for LINT formality */

#endif

}

#endif