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"
36 /*+ A private memory heap is used to reduce the number of malloc calls that are made, the Heap type is a pointer to this. +*/
37 typedef struct _Heap
*Heap
;
39 /*+ A structure containing all of the information about the private heap in a linked list. +*/
42 char* mem
; /*+ The memory that is private to the heap. +*/
43 Heap next
; /*+ The next Heap structure. +*/
46 /*+ Local variable to control the usage of the private heap; +*/
47 static Heap first
=NULL
; /*+ the first segment of memory on the private heap. +*/
48 static int heap_left
=0; /*+ the amount of space left in the current heap segment. +*/
50 static char* get_space(unsigned int l
);
51 static Heap
add_to_heap(unsigned int l
);
54 /*+ Variable used for debugging, not a good thing to do. what if more than 16384 mallocs? +*/
55 static void* addresses
[16384];
56 static char* files
[16384];
57 static int lines
[16384];
60 /*+ Variable used for debugging. +*/
61 static int malloc_count
=0;
62 static int realloc_count
=0;
63 static int free_count
=0;
67 /*++++++++++++++++++++++++++++++++++++++
68 A replacement malloc() function.
70 void* SafeMalloc Returns the address.
72 unsigned int size The size of the memory to allocate.
74 char* file The file that the function is called from.
76 int line The line number that the function is called from.
77 ++++++++++++++++++++++++++++++++++++++*/
79 void* SafeMalloc(unsigned int size
,char* file
,int line
)
81 void* rptr
=malloc(size
);
84 printf("$$Malloc #%5d of %4d bytes at %08lx (%s:%3d)\n",malloc_count
+1,size
,(long)rptr
,file
,line
);
87 if(malloc_count
==(sizeof(addresses
)/sizeof(addresses
[0])))
88 {fprintf(stderr
,"$$Too many Mallocs to log, edit memory.c\n");exit(3);}
89 addresses
[malloc_count
]=(void*)rptr
;
90 files
[malloc_count
]=file
;
91 lines
[malloc_count
]=line
;
95 if(!rptr
) printf("$$Warning Malloc() returning NULL (%s:%3d)\n",file
,line
);
98 if(!rptr
) printf("Warning Malloc() returning NULL (%s:%3d)\n",file
,line
);
105 /*++++++++++++++++++++++++++++++++++++++
106 A replacement calloc() function.
108 void* SafeCalloc Returns the address.
110 unsigned int n The number of items to allocate.
112 unsigned int size The size of the memory to allocate.
114 char* file The file that the function is called from.
116 int line The line number that the function is called from.
117 ++++++++++++++++++++++++++++++++++++++*/
119 void* SafeCalloc(unsigned int n
,unsigned int size
,char* file
,int line
)
121 void* rptr
=calloc(n
,size
);
124 printf("$$Calloc #%5d of %4d bytes at %08lx (%s:%3d)\n",malloc_count
+1,size
,(long)rptr
,file
,line
);
127 if(malloc_count
==(sizeof(addresses
)/sizeof(addresses
[0])))
128 {fprintf(stderr
,"$$Too many Mallocs to log, edit memory.c\n");exit(3);}
129 addresses
[malloc_count
]=(void*)rptr
;
130 files
[malloc_count
]=file
;
131 lines
[malloc_count
]=line
;
135 if(!rptr
) printf("$$Warning Calloc() returning NULL (%s:%3d)\n",file
,line
);
138 if(!rptr
) printf("Warning Calloc() returning NULL (%s:%3d)\n",file
,line
);
145 /*++++++++++++++++++++++++++++++++++++++
146 A replacement realloc() function.
148 void* SafeRealloc Returns the address.
150 void* ptr The old pointer.
152 unsigned int size The size of the new memory to allocate.
154 char* file The file that the function is called from.
156 int line The line number that the function is called from.
157 ++++++++++++++++++++++++++++++++++++++*/
159 void* SafeRealloc(void* ptr
,unsigned int size
,char* file
,int line
)
161 void* rptr
=realloc(ptr
,size
);
164 printf("$$Realloc #%4d of %4d bytes at %08lx (old %08lx) (%s:%3d)\n",realloc_count
+1,size
,(long)rptr
,(long)ptr
,file
,line
);
169 for(i
=0;i
<malloc_count
;i
++)
170 if(addresses
[i
]==(void*)ptr
)
171 {addresses
[i
]=rptr
;break;}
173 printf("$$Realloc() called for a non Malloced pointer %08lx (%s:%3d)\n",(long)ptr
,file
,line
);
178 if(!rptr
) printf("$$Warning Realloc() returning NULL (%s:%3d)\n",file
,line
);
181 if(!rptr
) printf("Warning Realloc() returning NULL (%s:%3d)\n",file
,line
);
188 /*++++++++++++++++++++++++++++++++++++++
189 A replacement free() function.
191 void* ptr The pointer that is to be freed up.
193 char* file The file that the function is called from.
195 int line The line number that the function is called from.
196 ++++++++++++++++++++++++++++++++++++++*/
198 void SafeFree(void* ptr
,char* file
,int line
)
201 printf("$$Free #%5d at %08lx (%s:%3d)\n",free_count
+1,(long)ptr
,file
,line
);
206 for(i
=0;i
<malloc_count
;i
++)
207 if(addresses
[i
]==(void*)ptr
)
208 {addresses
[i
]=(void*)1;break;}
210 printf("$$Free() called for a non Malloced pointer %08lx (%s:%3d)\n",(long)ptr
,file
,line
);
215 if(!ptr
) printf("$$Calling Free() on NULL (%s:%3d)\n",file
,line
);
219 if(!ptr
) printf("Calling Free() on NULL (%s:%3d)\n",file
,line
);
227 /*++++++++++++++++++++++++++++++++++++++
228 A function to copy a string on the public global heap.
230 char* SafeMallocString Returns the copy of the string.
232 char* x The string to be copied.
234 char* file The file that the function is called from.
236 int line The line number that the function is called from.
237 ++++++++++++++++++++++++++++++++++++++*/
239 char* SafeMallocString(char* x
,char* file
,int line
)
245 t
=(char*)SafeMalloc(strlen(x
)+1,file
,line
);
253 /*++++++++++++++++++++++++++++++++++++++
254 A function to copy a string on the local private memory heap.
256 char* CopyString Returns the copy of the string.
258 char* x The string to be copied.
259 ++++++++++++++++++++++++++++++++++++++*/
261 char* CopyString(char* x
)
267 t
=get_space(strlen(x
)+1);
275 /*++++++++++++++++++++++++++++++++++++++
276 A function to concatenate a number of strings.
278 char* ConcatStrings Returns the a pointer to the new string.
280 int n The number of strings
282 char* s The first string.
284 ... The other strings, 'n' including 's'.
286 Any of the strings that are inputs can be NULL, in this case they are quietly ignored.
287 ++++++++++++++++++++++++++++++++++++++*/
289 char* ConcatStrings(int n
,char* s
, ...)
305 str
=va_arg(ap
, char *);
317 t
=get_space(l
+1); t
[0]=0;
328 str
=va_arg(ap
, char *);
343 /*++++++++++++++++++++++++++++++++++++++
344 Prints out the number of mallocs / reallocs and frees.
345 ++++++++++++++++++++++++++++++++++++++*/
347 void PrintMemoryStatistics(void)
351 "$$Memory usage : %5d Malloc()/Calloc() calls\n"
352 "$$ %5d Realloc() calls\n"
353 "$$ %5d Free() calls\n"
354 "$$ %5d Net calls (Malloc-Free)\n",
355 malloc_count
,realloc_count
,free_count
,malloc_count
-free_count
);
361 for(i
=0;i
<malloc_count
;i
++)
362 if(addresses
[i
]!=(void*)1)
363 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
]);
369 /*++++++++++++++++++++++++++++++++++++++
370 Tidies up the local heap of memory.
371 ++++++++++++++++++++++++++++++++++++++*/
373 void TidyMemory(void)
392 /*+ The size of each of the heap allocations +*/
393 #define HEAP_INC 8192
395 /*+ The size of a string that is large enough to have it's own mallocation. +*/
396 #define SMALL_STRING 256
398 /*++++++++++++++++++++++++++++++++++++++
399 A function to get some memory for a string, allocate a new heap structure if needed.
401 char* get_space Returns a pointer to enough space.
403 unsigned int l The amount of space that is needed.
404 ++++++++++++++++++++++++++++++++++++++*/
406 static char* get_space(unsigned int l
)
408 static Heap current
=NULL
;
411 if(l
<= SMALL_STRING
)
415 current
=add_to_heap(HEAP_INC
);
421 r
=¤t
->mem
[heap_left
]; /* Work downwards */
425 Heap h
=add_to_heap(l
);
433 /*++++++++++++++++++++++++++++++++++++++
434 Add some bytes to the privately maintained memory heap.
436 Heap add_to_heap Returns a pointer to the required memory.
438 unsigned int l The size of the memory that is required.
439 ++++++++++++++++++++++++++++++++++++++*/
441 static Heap
add_to_heap(unsigned int l
)
448 *h
=(Heap
)Malloc(sizeof(struct _Heap
));
450 (*h
)->mem
=(char*)Malloc(l
);