112 memcpy(data, ptr,
size);
133 memcpy(s, str, len + 1);
149 #define SIZE(_size) (sizeof(WsMemBlockHdr) + (_size)) 151 #define MAGIC 0xfe01fa77 153 struct WsMemBlockHdrRec
156 struct WsMemBlockHdrRec *next;
157 struct WsMemBlockHdrRec *prev;
163 typedef struct WsMemBlockHdrRec WsMemBlockHdr;
166 WsMemBlockHdr *blocks = NULL;
169 unsigned int num_blocks = 0;
172 unsigned int max_num_blocks = 0;
179 size_t max_balance = 0;
182 unsigned int alloc_number = 0;
185 unsigned int num_successful_allocs = -1;
188 static void add_block(WsMemBlockHdr *b,
size_t size,
const char *
file,
int line)
207 if (balance > max_balance)
208 max_balance = balance;
210 if (num_blocks > max_num_blocks)
211 max_num_blocks = num_blocks;
215 static void remove_block(WsMemBlockHdr *b)
217 if (b->magic != MAGIC)
218 ws_fatal(
"remove_block(): invalid magic\n");
221 b->next->prev = b->prev;
223 b->prev->next = b->next;
230 memset(b, 0xfe, SIZE(b->size));
234 void *ws_malloc_i(
size_t size,
const char *
file,
int line)
238 if (alloc_number++ >= num_successful_allocs)
252 void *ws_calloc_i(
size_t num,
size_t size,
const char *
file,
int line)
254 void *p = ws_malloc_i(num *
size,
file, line);
257 memset(p, 0, num *
size);
263 void *ws_realloc_i(
void *ptr,
size_t size,
const char *
file,
int line)
265 WsMemBlockHdr *b = ((WsMemBlockHdr *) ptr) - 1;
269 return ws_malloc_i(
size,
file, line);
280 memcpy(n, ptr, b->size);
290 void *ws_memdup_i(
const void *ptr,
size_t size,
const char *
file,
int line)
292 void *p = ws_malloc_i(
size + 1,
file, line);
295 unsigned char *cp = (
unsigned char *) p;
297 memcpy(p, ptr,
size);
305 void *ws_strdup_i(
const char *str,
const char *
file,
int line)
307 return ws_memdup_i(str, strlen(str),
file, line);
311 void ws_free_i(
void *ptr)
313 WsMemBlockHdr *b = ((WsMemBlockHdr *) ptr) - 1;
323 int ws_has_leaks(
void)
325 return num_blocks || balance;
329 void ws_dump_blocks(
void)
333 fprintf(stderr,
"ws: maximum memory usage: %u blocks, %ld bytes\n",
334 max_num_blocks, (
long) max_balance);
335 fprintf(stderr,
"ws: number of allocs: %u\n", alloc_number);
337 if (num_blocks || balance) {
338 fprintf(stderr,
"ws: memory leaks: %u blocks, %ld bytes:\n",
339 num_blocks, (
long) balance);
341 for (b = blocks; b; b = b->next)
342 fprintf(stderr,
"%s:%d: %ld\n", b->file, b->line, (
long) b->size);
347 void ws_clear_leaks(
unsigned int num_successful_allocs_)
350 num_successful_allocs = num_successful_allocs_;
void ws_fatal(char *fmt,...)
void * ws_calloc(size_t num, size_t size)
void * ws_realloc(void *ptr, size_t size)
void * ws_memdup(const void *ptr, size_t size)
void * ws_strdup(const char *str)
void * ws_malloc(size_t size)