home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Power-Programmierung
/
CD1.mdf
/
magazine
/
drdobbs
/
1988
/
06
/
dmalloc.c
< prev
next >
Wrap
Text File
|
1979-12-31
|
9KB
|
283 lines
Listing 1 -- dmalloc.c
____________________________________________________________________________
1| #include <stdio.h>
2| #include <stdlib.h> /* for prototypes only */
3| #include <malloc.h> /* for prototypes only */
4| #include <string.h> /* for prototypes only */
5| #include <dos.h> /* SREGS definition */
6|
7| /* DMALLOC.C Debugging versions of malloc and free for
8| * the compact model.
9| */
10|
11| #define MAXPTR 2048 /* max # of pointers to check */
12|
13| static char huge* *Pointers = NULL;
14| static int Nel = 0; /*# elements in Pointers */
15| static int Debugging_on = 0;
16| static unsigned long Total_mem = 0L;
17|
18| /*------------------------------------------------------------*/
19| int malloc_checking ( int on );
20| void *dmalloc ( unsigned size );
21| void *dcalloc ( size_t n, size_t size );
22| void dfree ( char huge* p );
23| void *find_in_table ( char huge* key, int *found );
24| void add_to_table ( char huge* p );
25| int remove_from_table ( char huge* p );
26| unsigned long memory_used ( void );
27| /*------------------------------------------------------------*/
28|
29| int malloc_checking( on )
30| {
31| /* Call this routine with a true argument to enable the
32| * debugging features. Calling it with a false argument
33| * frees all memory used for the checking.
34| */
35|
36| if( !(Debugging_on = on) )
37| {
38| Nel = 0;
39| if( Pointers )
40| free( Pointers );
41| Pointers = NULL;
42| }
43| else
44| {
45| if( !Pointers &&
46| !(Pointers = malloc(MAXPTR * sizeof(*Pointers))) )
47| {
48| fprintf(stderr, "No memory for pointer checking\n");
49| return 0;
50| }
51| }
52|
53| return 1;
54| }
55|
56| /*------------------------------------------------------------*/
57|
58| unsigned long memory_used()
59| {
60| return Total_mem;
61| }
62|
63| /*------------------------------------------------------------*/
64|
65| void *dcalloc( n, size )
66| size_t n, size;
67| {
68| void *p;
69|
70| if( p = dmalloc( size *= n ) )
71| memset( p, 0, size );
72|
73| return p;
74| }
75|
76| /*------------------------------------------------------------*/
77|
78| void *dmalloc( size )
79| unsigned size;
80| {
81| /* Debbugging version of malloc. If debugging is enabled,
82| * put the malloced pointer into the Pointers table before
83| * returning it.
84| */
85|
86| void huge* p;
87|
88| Total_mem += size;
89|
90| if( !Debugging_on )
91| return malloc( size );
92|
93| if( !(p = (void huge*) malloc( size )) )
94| {
95| fprintf(stderr,"Malloc out of memory, returning NULL\n");
96| return NULL;
97| }
98|
99| fprintf( stderr, "malloc(%u) = %p\n", size, p );
100| add_to_table( p );
101| return p;
102| }
103|
104| /*------------------------------------------------------------*/
105|
106| void dfree( p )
107| char huge* p;
108| {
109| /* Debugging verion of free(). If debugging is enabled,
110| * check that the returned pointer is in the Pointers[]
111| * table before allowing it to be freed(). The return-
112| * address computation is far from portable, but it's
113| * useful nonetheless.
114| */
115|
116| struct SREGS seg;
117|
118| Total_mem -= _msize( p );
119|
120| if( !Debugging_on )
121| {
122| free( p );
123| return;
124| }
125|
126| if( !remove_from_table(p) )
127| {
128| segread( &seg );
129| fprintf( stderr,"free() [Called from %04x:%04x]: BAD POINTER %p\n",
130| seg.cs, ((void(**)())( &p ))[-1], p);
131| exit( 1 );
132| }
133| else
134| {
135| free( p );
136| fprintf( stderr, "free(%p) successful\n", p );
137| }
138| }
139|
140| /*------------------------------------------------------------*/
141|
142| static void *find_in_table( key, found )
143| char huge* key;
144| int *found; /* set to 1 if found */
145| {
146| /* Do a binary search in Pointers for key. If it's there
147| * set *found to true and return a pointer to it; otherwise,
148| * set *found to false and return a pointer to the place
149| * in the table that it should go.
150| */
151|
152| char huge* *p; /* Pointer to middle element */
153| char huge* *array; /* Pointer to base of array */
154| int mid; /* Array index of middle element */
155| int size;
156|
157| *found = 0;
158| if( !(size = Nel) )
159| return Pointers;
160|
161| array = Pointers;
162|
163| while( size > 0 )
164| {
165| mid = size >> 1 ;
166| p = array + mid ;
167|
168| if ( key == *p )
169| {
170| *found = 1;
171| return p;
172| }
173| else if ( key < *p )
174| {
175| size = mid ;
176| }
177| else
178| {
179| array = p + 1;
180| size -= mid+1;
181| }
182| }
183|
184| return (void *)( *p > key ? p : p + 1 );
185| }
186|
187| /*------------------------------------------------------------*/
188|
189| static void add_to_table(p)
190| char huge* p;
191| {
192| /* Add p to the Pointers table. If it's allready there
193| * print an error message.
194| */
195|
196| char huge* *tabp;
197| int found;
198|
199| tabp = find_in_table( p, &found );
200|
201| if( found )
202| {
203| fprintf(stderr, "Malloc returned the same pointer twice!\n");
204| exit( 1 );
205| }
206|
207| if( Nel >= MAXPTR )
208| {
209| fprintf(stderr,
210| "Internal error [dmalloc()] too many pointers!\n");
211| exit( 1 );
212| }
213|
214| if( tabp == &Pointers[Nel] )
215| Pointers[Nel++] = p;
216| else
217| {
218| ++Nel;
219| memmove( tabp+1, tabp,
220| (Nel - (tabp-Pointers)) * sizeof(*Pointers) );
221| *tabp = p;
222| }
223| }
224|
225| /*------------------------------------------------------------*/
226|
227| static int remove_from_table(p)
228| char huge *p;
229| {
230| /* Remove p from the pointers table, return 0 if it's not
231| * there, 1 otherwise.
232| */
233|
234| char huge* *tabp;
235| int found;
236|
237| tabp = find_in_table( p, &found );
238|
239| if( !found )
240| return 0;
241|
242| --Nel;
243| memmove( tabp, tabp+1,
244| (Nel - (tabp-Pointers)) * sizeof(*Pointers) );
245| return 1;
246| }
247|
248| /*------------------------------------------------------------*/
249|
250| #ifdef MAIN
251| main()
252| {
253| void *p1, *p2, *p3, *p4, *p5;
254| int i;
255|
256| malloc_checking( 1 );
257|
258| p1 = dmalloc( 32767 ); ptab();
259| p2 = dmalloc( 32767 ); ptab();
260| p3 = dmalloc( 32767 ); ptab();
261| p4 = dmalloc( 32767 ); ptab();
262| p5 = dmalloc( 32767 ); ptab();
263|
264| dfree( p1 ); ptab();
265| dfree( p2 ); ptab();
266| dfree( p3 ); ptab();
267| dfree( p4 ); ptab();
268| dfree( p5 ); ptab();
269| }
270|
271| /*------------------------------------------------------------*/
272|
273| ptab()
274| {
275| int i;
276| printf("\tNel = %d\n", Nel );
277| for( i = 0; i < Nel; ++i )
278| printf("\tPointers[%d] = %p\n", i, Pointers[i] );
279| }
280| #endif