- cleaned up file (variable name changes, etc)
This commit is contained in:
+65
-58
@@ -32,99 +32,108 @@
|
|||||||
|
|
||||||
#ifdef LEAK_DETECTIVE
|
#ifdef LEAK_DETECTIVE
|
||||||
|
|
||||||
|
typedef union memory_hdr_u memory_hdr_t;
|
||||||
|
|
||||||
union mhdr {
|
union memory_hdr_u {
|
||||||
struct {
|
struct {
|
||||||
const char *file;
|
const char *filename;
|
||||||
size_t line;
|
size_t line;
|
||||||
size_t length;
|
size_t size_of_memory;
|
||||||
union mhdr *older, *newer;
|
memory_hdr_t *older, *newer;
|
||||||
} i; /* info */
|
} info; /* info */
|
||||||
unsigned long junk; /* force maximal alignment */
|
unsigned long junk; /* force maximal alignment */
|
||||||
};
|
};
|
||||||
|
|
||||||
static union mhdr *allocs = NULL;
|
/**
|
||||||
|
* global list of allocations
|
||||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
*
|
||||||
|
* thread-save through mutex
|
||||||
|
*/
|
||||||
|
static memory_hdr_t *allocations = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocates memory with LEAK_DETECTION and returns an empty data area filled with zeros
|
* Mutex to ensure, all functions are thread-save
|
||||||
*
|
*/
|
||||||
* use this function not directly, only with assigned macros
|
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* described in header
|
||||||
*/
|
*/
|
||||||
void * allocate(size_t bytes, char * file,int line)
|
void * allocate(size_t bytes, char * file,int line)
|
||||||
{
|
{
|
||||||
union mhdr *p = malloc(sizeof(union mhdr) + bytes);
|
memory_hdr_t *allocated_memory = malloc(sizeof(memory_hdr_t) + bytes);
|
||||||
|
|
||||||
if (p == NULL)
|
if (allocated_memory == NULL)
|
||||||
{
|
{
|
||||||
return p;
|
return allocated_memory;
|
||||||
}
|
}
|
||||||
pthread_mutex_lock( &mutex);
|
|
||||||
p->i.line = line;
|
|
||||||
p->i.file = file;
|
|
||||||
p->i.length = bytes;
|
|
||||||
p->i.older = allocs;
|
|
||||||
if (allocs != NULL)
|
|
||||||
allocs->i.newer = p;
|
|
||||||
allocs = p;
|
|
||||||
p->i.newer = NULL;
|
|
||||||
|
|
||||||
memset(p+1, '\0', bytes);
|
pthread_mutex_lock( &mutex);
|
||||||
|
|
||||||
|
allocated_memory->info.line = line;
|
||||||
|
allocated_memory->info.filename = file;
|
||||||
|
allocated_memory->info.size_of_memory = bytes;
|
||||||
|
allocated_memory->info.older = allocations;
|
||||||
|
if (allocations != NULL)
|
||||||
|
{
|
||||||
|
allocations->info.newer = allocated_memory;
|
||||||
|
}
|
||||||
|
allocations = allocated_memory;
|
||||||
|
allocated_memory->info.newer = NULL;
|
||||||
|
|
||||||
|
/* fill memory with zero's */
|
||||||
|
memset(allocated_memory+1, '\0', bytes);
|
||||||
pthread_mutex_unlock( &mutex);
|
pthread_mutex_unlock( &mutex);
|
||||||
return p+1;
|
/* real memory starts after header */
|
||||||
|
return (allocated_memory+1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Frees memory with LEAK_DETECTION
|
* described in header
|
||||||
*
|
|
||||||
* use this function not directly, only with assigned macros
|
|
||||||
*/
|
*/
|
||||||
void free_pointer(void * pointer)
|
void free_pointer(void * pointer)
|
||||||
{
|
{
|
||||||
union mhdr *p;
|
memory_hdr_t *allocated_memory;
|
||||||
|
|
||||||
if (pointer == NULL)
|
if (pointer == NULL)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
pthread_mutex_lock( &mutex);
|
pthread_mutex_lock( &mutex);
|
||||||
p = ((union mhdr *)pointer) - 1;
|
allocated_memory = ((memory_hdr_t *)pointer) - 1;
|
||||||
|
|
||||||
if (p->i.older != NULL)
|
if (allocated_memory->info.older != NULL)
|
||||||
{
|
{
|
||||||
assert(p->i.older->i.newer == p);
|
assert(allocated_memory->info.older->info.newer == allocated_memory);
|
||||||
p->i.older->i.newer = p->i.newer;
|
allocated_memory->info.older->info.newer = allocated_memory->info.newer;
|
||||||
}
|
}
|
||||||
if (p->i.newer == NULL)
|
if (allocated_memory->info.newer == NULL)
|
||||||
{
|
{
|
||||||
assert(p == allocs);
|
assert(allocated_memory == allocations);
|
||||||
allocs = p->i.older;
|
allocations = allocated_memory->info.older;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
assert(p->i.newer->i.older == p);
|
assert(allocated_memory->info.newer->info.older == allocated_memory);
|
||||||
p->i.newer->i.older = p->i.older;
|
allocated_memory->info.newer->info.older = allocated_memory->info.older;
|
||||||
}
|
}
|
||||||
pthread_mutex_unlock( &mutex);
|
pthread_mutex_unlock( &mutex);
|
||||||
free(p);
|
free(allocated_memory);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Reallocates memory with LEAK_DETECTION
|
* described in header
|
||||||
*
|
|
||||||
* use this function not directly, only with assigned macros
|
|
||||||
*/
|
*/
|
||||||
void * reallocate(void * old, size_t bytes, char * file,int line)
|
void * reallocate(void * old, size_t bytes, char * file,int line)
|
||||||
{
|
{
|
||||||
union mhdr *p;
|
memory_hdr_t *allocated_memory;
|
||||||
|
|
||||||
if (old == NULL)
|
if (old == NULL)
|
||||||
{
|
{
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
pthread_mutex_lock( &mutex);
|
pthread_mutex_lock( &mutex);
|
||||||
p = ((union mhdr *)old) - 1;
|
allocated_memory = ((memory_hdr_t *)old) - 1;
|
||||||
|
|
||||||
void *new_space = allocate(bytes,file,line);
|
void *new_space = allocate(bytes,file,line);
|
||||||
if (new_space == NULL)
|
if (new_space == NULL)
|
||||||
@@ -134,37 +143,35 @@ void * reallocate(void * old, size_t bytes, char * file,int line)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(new_space,old,p->i.length);
|
memcpy(new_space,old,allocated_memory->info.size_of_memory);
|
||||||
pthread_mutex_unlock( &mutex);
|
pthread_mutex_unlock( &mutex);
|
||||||
|
|
||||||
return new_space;
|
return new_space;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* Reports memory-leaks
|
* described in header
|
||||||
*
|
|
||||||
*/
|
*/
|
||||||
void report_memory_leaks(void)
|
void report_memory_leaks(void)
|
||||||
{
|
{
|
||||||
union mhdr
|
memory_hdr_t *p = allocations,
|
||||||
*p = allocs,
|
*pprev = NULL;
|
||||||
*pprev = NULL;
|
|
||||||
unsigned long n = 0;
|
unsigned long n = 0;
|
||||||
pthread_mutex_lock( &mutex);
|
pthread_mutex_lock( &mutex);
|
||||||
|
|
||||||
while (p != NULL)
|
while (p != NULL)
|
||||||
{
|
{
|
||||||
assert(pprev == p->i.newer);
|
assert(pprev == p->info.newer);
|
||||||
pprev = p;
|
pprev = p;
|
||||||
p = p->i.older;
|
p = p->info.older;
|
||||||
n++;
|
n++;
|
||||||
if (p == NULL || pprev->i.file != p->i.file)
|
if (p == NULL || pprev->info.filename != p->info.filename)
|
||||||
{
|
{
|
||||||
if (n != 1)
|
if (n != 1)
|
||||||
fprintf(stderr,"leak: %lu * File %s, Line %d\n", n, pprev->i.file,pprev->i.line);
|
fprintf(stderr,"leak: %lu * File %s, Line %d\n", n, pprev->info.filename,pprev->info.line);
|
||||||
else
|
else
|
||||||
fprintf(stderr,"leak: File %s, Line %d\n", pprev->i.file,pprev->i.line);
|
fprintf(stderr,"leak: File %s, Line %d\n", pprev->info.filename,pprev->info.line);
|
||||||
n = 0;
|
n = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,16 +26,60 @@
|
|||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function to allocate a special type
|
||||||
|
*
|
||||||
|
* @param thing object on it a sizeof is performed
|
||||||
|
*/
|
||||||
#define allocator_alloc_thing(thing) (allocator_alloc(sizeof(thing)))
|
#define allocator_alloc_thing(thing) (allocator_alloc(sizeof(thing)))
|
||||||
|
|
||||||
#ifdef LEAK_DETECTIVE
|
#ifdef LEAK_DETECTIVE
|
||||||
|
/**
|
||||||
|
* Allocates memory with LEAK_DETECTION and
|
||||||
|
* returns an empty data area filled with zeros
|
||||||
|
*
|
||||||
|
* @warning use this function not directly, only with assigned macros
|
||||||
|
* allocator_alloc and allocator_alloc_thing
|
||||||
|
*
|
||||||
|
* @param bytes number of bytes to allocate
|
||||||
|
* @param file filename from which the memory is allocated
|
||||||
|
* @param line line number in specific file
|
||||||
|
* @return allocated memory area
|
||||||
|
*/
|
||||||
void * allocate(size_t bytes, char * file,int line);
|
void * allocate(size_t bytes, char * file,int line);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reallocates memory with LEAK_DETECTION and
|
||||||
|
* returns an empty data area filled with zeros
|
||||||
|
*
|
||||||
|
* @warning use this function not directly, only with assigned macro
|
||||||
|
* allocator_realloc
|
||||||
|
*
|
||||||
|
* @param old pointer to the old data area
|
||||||
|
* @param bytes number of bytes to allocate
|
||||||
|
* @param file filename from which the memory is allocated
|
||||||
|
* @param line line number in specific file
|
||||||
|
* @return reallocated memory area
|
||||||
|
*/
|
||||||
void * reallocate(void * old, size_t bytes, char * file, int line);
|
void * reallocate(void * old, size_t bytes, char * file, int line);
|
||||||
|
/**
|
||||||
|
* Frees memory with LEAK_DETECTION
|
||||||
|
*
|
||||||
|
* @warning use this function not directly, only with assigned macro
|
||||||
|
* allocator_free
|
||||||
|
*
|
||||||
|
* @param pointer pointer to the data area to free
|
||||||
|
*/
|
||||||
void free_pointer(void * pointer);
|
void free_pointer(void * pointer);
|
||||||
|
|
||||||
#define allocator_alloc(bytes) (allocate(bytes,__FILE__,__LINE__))
|
#define allocator_alloc(bytes) (allocate(bytes,__FILE__,__LINE__))
|
||||||
#define allocator_realloc(old,bytes) (reallocate(old,bytes,__FILE__, __LINE__))
|
#define allocator_realloc(old,bytes) (reallocate(old,bytes,__FILE__, __LINE__))
|
||||||
#define allocator_free(pointer) (free_pointer(pointer))
|
#define allocator_free(pointer) (free_pointer(pointer))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Report memory leaks to stderr
|
||||||
|
*/
|
||||||
void report_memory_leaks(void);
|
void report_memory_leaks(void);
|
||||||
#else
|
#else
|
||||||
#define allocator_alloc(bytes) (malloc(bytes))
|
#define allocator_alloc(bytes) (malloc(bytes))
|
||||||
|
|||||||
Reference in New Issue
Block a user