1 /***************************************
4 C Cross Referencing & Documentation tool. Version 1.5.
6 Memory management functions
7 ******************/ /******************
8 Written by Andrew M. Bishop
10 This file Copyright 1995,96,97 Andrew M. Bishop
11 It may be distributed under the GNU Public License, version 2, or
12 any higher version. See section COPYING of the GNU Public license
13 for conditions under which this file may be redistributed.
14 ***************************************/
16 /*+ The amount of debugging, non-zero for totals, 2 for logging, 4 for printing each call. +*/
19 /* The configure output */
21 #include "autoconfig.h"
35 /*+ A private memory heap is used to reduce the number of malloc calls that are made, the Heap type is a pointer to this. +*/
36 typedef struct _Heap
*Heap
;
38 /*+ A structure containing all of the information about the private heap in a linked list. +*/
41 char* mem
; /*+ The memory that is private to the heap. +*/
42 Heap next
; /*+ The next Heap structure. +*/
45 /*+ Local variable to control the usage of the private heap; +*/
46 static Heap first
=NULL
; /*+ the first segment of memory on the private heap. +*/
47 static int heap_left
=0; /*+ the amount of space left in the current heap segment. +*/
49 static char* get_space(unsigned int l
);
50 static Heap
add_to_heap(unsigned int l
);
53 /*+ Variable used for debugging, not a good thing to do. what if more than 16384 mallocs? +*/
54 static void* addresses
[16384];
55 static char* files
[16384];
56 static int lines
[16384];
59 /*+ Variable used for debugging. +*/
60 static int malloc_count
=0;
61 static int realloc_count
=0;
62 static int free_count
=0;
66 /*++++++++++++++++++++++++++++++++++++++
67 A replacement malloc() function.
69 void* SafeMalloc Returns the address.
71 unsigned int size The size of the memory to allocate.
73 char* file The file that the function is called from.
75 int line The line number that the function is called from.
76 ++++++++++++++++++++++++++++++++++++++*/
78 void* SafeMalloc(unsigned int size
,char* file
,int line
)
80 void* rptr
=malloc(size
);
83 printf("$$Malloc #%5d of %4d bytes at %08lx (%s:%3d)\n",malloc_count
+1,size
,(long)rptr
,file
,line
);
86 if(malloc_count
==(sizeof(addresses
)/sizeof(addresses
[0])))
87 {fprintf(stderr
,"$$Too many Mallocs to log, edit memory.c\n");exit(3);}
88 addresses
[malloc_count
]=(void*)rptr
;
89 files
[malloc_count
]=file
;
90 lines
[malloc_count
]=line
;
94 if(!rptr
) printf("$$Warning Malloc() returning NULL (%s:%3d)\n",file
,line
);
97 if(!rptr
) printf("Warning Malloc() returning NULL (%s:%3d)\n",file
,line
);
104 /*++++++++++++++++++++++++++++++++++++++
105 A replacement calloc() function.
107 void* SafeCalloc Returns the address.
109 unsigned int n The number of items to allocate.
111 unsigned int size The size of the memory to allocate.
113 char* file The file that the function is called from.
115 int line The line number that the function is called from.
116 ++++++++++++++++++++++++++++++++++++++*/
118 void* SafeCalloc(unsigned int n
,unsigned int size
,char* file
,int line
)
120 void* rptr
=calloc(n
,size
);
123 printf("$$Calloc #%5d of %4d bytes at %08lx (%s:%3d)\n",malloc_count
+1,size
,(long)rptr
,file
,line
);
126 if(malloc_count
==(sizeof(addresses
)/sizeof(addresses
[0])))
127 {fprintf(stderr
,"$$Too many Mallocs to log, edit memory.c\n");exit(3);}
128 addresses
[malloc_count
]=(void*)rptr
;
129 files
[malloc_count
]=file
;
130 lines
[malloc_count
]=line
;
134 if(!rptr
) printf("$$Warning Calloc() returning NULL (%s:%3d)\n",file
,line
);
137 if(!rptr
) printf("Warning Calloc() returning NULL (%s:%3d)\n",file
,line
);
144 /*++++++++++++++++++++++++++++++++++++++
145 A replacement realloc() function.
147 void* SafeRealloc Returns the address.
149 void* ptr The old pointer.
151 unsigned int size The size of the new memory to allocate.
153 char* file The file that the function is called from.
155 int line The line number that the function is called from.
156 ++++++++++++++++++++++++++++++++++++++*/
158 void* SafeRealloc(void* ptr
,unsigned int size
,char* file
,int line
)
160 void* rptr
=realloc(ptr
,size
);
163 printf("$$Realloc #%4d of %4d bytes at %08lx (old %08lx) (%s:%3d)\n",realloc_count
+1,size
,(long)rptr
,(long)ptr
,file
,line
);
168 for(i
=0;i
<malloc_count
;i
++)
169 if(addresses
[i
]==(void*)ptr
)
170 {addresses
[i
]=rptr
;break;}
172 printf("$$Realloc() called for a non Malloced pointer %08lx (%s:%3d)\n",(long)ptr
,file
,line
);
177 if(!rptr
) printf("$$Warning Realloc() returning NULL (%s:%3d)\n",file
,line
);
180 if(!rptr
) printf("Warning Realloc() returning NULL (%s:%3d)\n",file
,line
);
187 /*++++++++++++++++++++++++++++++++++++++
188 A replacement free() function.
190 void* ptr The pointer that is to be freed up.
192 char* file The file that the function is called from.
194 int line The line number that the function is called from.
195 ++++++++++++++++++++++++++++++++++++++*/
197 void SafeFree(void* ptr
,char* file
,int line
)
200 printf("$$Free #%5d at %08lx (%s:%3d)\n",free_count
+1,(long)ptr
,file
,line
);
205 for(i
=0;i
<malloc_count
;i
++)
206 if(addresses
[i
]==(void*)ptr
)
207 {addresses
[i
]=(void*)1;break;}
209 printf("$$Free() called for a non Malloced pointer %08lx (%s:%3d)\n",(long)ptr
,file
,line
);
214 if(!ptr
) printf("$$Calling Free() on NULL (%s:%3d)\n",file
,line
);
218 if(!ptr
) printf("Calling Free() on NULL (%s:%3d)\n",file
,line
);
226 /*++++++++++++++++++++++++++++++++++++++
227 A function to copy a string on the public global heap.
229 char* SafeMallocString Returns the copy of the string.
231 char* x The string to be copied.
233 char* file The file that the function is called from.
235 int line The line number that the function is called from.
236 ++++++++++++++++++++++++++++++++++++++*/
238 char* SafeMallocString(char* x
,char* file
,int line
)
244 t
=(char*)SafeMalloc(strlen(x
)+1,file
,line
);
252 /*++++++++++++++++++++++++++++++++++++++
253 A function to copy a string on the local private memory heap.
255 char* CopyString Returns the copy of the string.
257 char* x The string to be copied.
258 ++++++++++++++++++++++++++++++++++++++*/
260 char* CopyString(char* x
)
266 t
=get_space(strlen(x
)+1);
274 /*++++++++++++++++++++++++++++++++++++++
275 A function to concatenate a number of strings.
277 char* ConcatStrings Returns the a pointer to the new string.
279 int n The number of strings
281 char* s The first string.
283 ... The other strings, 'n' including 's'.
285 Any of the strings that are inputs can be NULL, in this case they are quietly ignored.
286 ++++++++++++++++++++++++++++++++++++++*/
288 char* ConcatStrings(int n
,char* s
, ...)
304 str
=va_arg(ap
, char *);
316 t
=get_space(l
+1); t
[0]=0;
327 str
=va_arg(ap
, char *);
342 /*++++++++++++++++++++++++++++++++++++++
343 Prints out the number of mallocs / reallocs and frees.
344 ++++++++++++++++++++++++++++++++++++++*/
346 void PrintMemoryStatistics(void)
350 "$$Memory usage : %5d Malloc()/Calloc() calls\n"
351 "$$ %5d Realloc() calls\n"
352 "$$ %5d Free() calls\n"
353 "$$ %5d Net calls (Malloc-Free)\n",
354 malloc_count
,realloc_count
,free_count
,malloc_count
-free_count
);
360 for(i
=0;i
<malloc_count
;i
++)
361 if(addresses
[i
]!=(void*)1)
362 printf("$$Malloc #%5d at address %08lx is not freed (%s:%3d) = '%s'\n",i
+1,(long)addresses
[i
],files
[i
],lines
[i
],(char*)addresses
[i
]);
368 /*++++++++++++++++++++++++++++++++++++++
369 Tidies up the local heap of memory.
370 ++++++++++++++++++++++++++++++++++++++*/
372 void TidyMemory(void)
391 /*+ The size of each of the heap allocations +*/
392 #define HEAP_INC 8192
394 /*+ The size of a string that is large enough to have it's own mallocation. +*/
395 #define SMALL_STRING 256
397 /*++++++++++++++++++++++++++++++++++++++
398 A function to get some memory for a string, allocate a new heap structure if needed.
400 char* get_space Returns a pointer to enough space.
402 unsigned int l The amount of space that is needed.
403 ++++++++++++++++++++++++++++++++++++++*/
405 static char* get_space(unsigned int l
)
407 static Heap current
=NULL
;
410 if(l
<= SMALL_STRING
)
414 current
=add_to_heap(HEAP_INC
);
420 r
=¤t
->mem
[heap_left
]; /* Work downwards */
424 Heap h
=add_to_heap(l
);
432 /*++++++++++++++++++++++++++++++++++++++
433 Add some bytes to the privately maintained memory heap.
435 Heap add_to_heap Returns a pointer to the required memory.
437 unsigned int l The size of the memory that is required.
438 ++++++++++++++++++++++++++++++++++++++*/
440 static Heap
add_to_heap(unsigned int l
)
447 *h
=(Heap
)Malloc(sizeof(struct _Heap
));
449 (*h
)->mem
=(char*)Malloc(l
);