T
Tarique
I have tried writing a bare bone very naive storage allocator , my
replacement for malloc (Although it still uses malloc to get memory from
the system ,only once ) I have a question here :
1.Ive just realised that FOOTERBLOCK evaluates to zero How do I include
the size of the footer structure everywhere so that it works with
pointer arithmetic ??
The tag table only stores the relevant information which can be later
used to determine memory leak. All malloc calls are tagged in this table
and all relevant free calls will delete the tags Thus at the end if I
don't end up with any tags in the table , no leaks are present.
If I need to post anything from the tag_table file , please let me know
Also, please provide useful suggestions on improving the design/code
structure.
Thanks & Regards
Here is the code :
/* MemRoutines.c*/
#include "MemRoutines.h"
#include "TagTable.h"
#define ALIGNMENT 8 /*sizeof(double)*/
#define INITALLOC 4096 /*Minimum Memory Block Obtained from OS at once*/
#define BYTE1 0x12345678
#define BYTE2 0x00000000
#define BYTE3 0x1234ABCD
#define BYTE4 0xFFFFFFFF
/* -------------------------------------------------
* |next |size |16 | User |16 |
* |Free | of |byte | Memory |byte |
* |Add |block|picket| Space |picket|
* -------------------------------------------------
* |<---header------->|^Address returned
* ^---Size-------------^
* ^-----------------Memory from OS----------------^
union header {
struct {
union header* next;
union header* prev;
size_t size;
int h4byte1;
int h4byte2;
int h4byte3;
int h4byte4;
}s;
double dummy_align_var;
};
static union header* freep = NULL;
struct footer{
int f4byte1;
int f4byte2;
int f4byte3;
int f4byte4;
};
static size_t align(size_t size){
return ((size + ALIGNMENT - 1) & ~(ALIGNMENT - 1));
}
#define FOOTERBLOCK align(sizeof(struct footer)/sizeof(union header))
static void write_header( union header* hptr,
union header* nptr,
union header* pptr,
size_t sizep){
hptr->s.next = nptr ;
hptr->s.prev = pptr;
hptr->s.size = sizep;
hptr->s.h4byte1 = BYTE1;
hptr->s.h4byte2 = BYTE2;
hptr->s.h4byte3 = BYTE3;
hptr->s.h4byte4 = BYTE4;
return ;
}
static void write_footer( struct footer* footp){
footp->f4byte1 = BYTE1; footp->f4byte2 = BYTE2;
footp->f4byte3 = BYTE3; footp->f4byte4 = BYTE4;
return;
}
static union header* getmemory(size_t n){
union header* BigMem = NULL ;
if ( n < INITALLOC ) n = INITALLOC;
if(( BigMem = malloc( n * sizeof(union header))) == NULL )
return NULL;
write_header(BigMem, NULL, NULL, n);
return BigMem;
}
void* my_malloc(char* filename,unsigned int lineno,size_t request){
union header* p = NULL;
union header* q = NULL;
size_t reqblocks = 0;
char* trailer_ptr = NULL;
struct footer* footptr = NULL;
reqblocks = ((request + sizeof(union header) -1)/sizeof(union header))\
+ FOOTERBLOCK + 1 ;
if( !is_table_initialised() ){
initialise_table();
p = getmemory( reqblocks );
if( p == NULL )
return NULL;
else {
if( p->s.size > reqblocks ){
p->s.size = reqblocks;
p->s.next = p + 2 + reqblocks + FOOTERBLOCK ;
}
else
p->s.next = NULL ;
trailer_ptr = (void*)((char*)( p + 1 ) + request);
footptr = (struct footer*) trailer_ptr;
write_footer(footptr);
freep = p + 1 + reqblocks + FOOTERBLOCK ;
write_header(freep, NULL, p + 1,(reqblocks < p->s.size ?\
(p->s.size - reqblocks) : reqblocks));
add_tag(filename,lineno, p, p + 1, request);
return (void*)( p + 1 );
}
}
else {
p = freep;
while( p != NULL && p->s.size < reqblocks ){
q = p;
p = p->s.next;
}
if( p != NULL){
if ( p->s.size > reqblocks ){
p->s.size = reqblocks;
p->s.next = p + 2 + reqblocks + FOOTERBLOCK ;
}
else
p->s.next = NULL ;
trailer_ptr = (void*)((char*)( p + 1 ) + request);
footptr = (struct footer*) trailer_ptr;
write_footer(footptr);
freep = p + 1 + reqblocks + FOOTERBLOCK ;
write_header(freep, NULL, p + 1,(reqblocks < p->s.size ?\
(p->s.size - reqblocks) : reqblocks));
add_tag(filename,lineno, p, p + 1, request);
return (void*)( p + 1 );
}
}
return NULL;
}
replacement for malloc (Although it still uses malloc to get memory from
the system ,only once ) I have a question here :
1.Ive just realised that FOOTERBLOCK evaluates to zero How do I include
the size of the footer structure everywhere so that it works with
pointer arithmetic ??
The tag table only stores the relevant information which can be later
used to determine memory leak. All malloc calls are tagged in this table
and all relevant free calls will delete the tags Thus at the end if I
don't end up with any tags in the table , no leaks are present.
If I need to post anything from the tag_table file , please let me know
Also, please provide useful suggestions on improving the design/code
structure.
Thanks & Regards
Here is the code :
/* MemRoutines.c*/
#include "MemRoutines.h"
#include "TagTable.h"
#define ALIGNMENT 8 /*sizeof(double)*/
#define INITALLOC 4096 /*Minimum Memory Block Obtained from OS at once*/
#define BYTE1 0x12345678
#define BYTE2 0x00000000
#define BYTE3 0x1234ABCD
#define BYTE4 0xFFFFFFFF
/* -------------------------------------------------
* |next |size |16 | User |16 |
* |Free | of |byte | Memory |byte |
* |Add |block|picket| Space |picket|
* -------------------------------------------------
* |<---header------->|^Address returned
* ^---Size-------------^
* ^-----------------Memory from OS----------------^
union header {
struct {
union header* next;
union header* prev;
size_t size;
int h4byte1;
int h4byte2;
int h4byte3;
int h4byte4;
}s;
double dummy_align_var;
};
static union header* freep = NULL;
struct footer{
int f4byte1;
int f4byte2;
int f4byte3;
int f4byte4;
};
static size_t align(size_t size){
return ((size + ALIGNMENT - 1) & ~(ALIGNMENT - 1));
}
#define FOOTERBLOCK align(sizeof(struct footer)/sizeof(union header))
static void write_header( union header* hptr,
union header* nptr,
union header* pptr,
size_t sizep){
hptr->s.next = nptr ;
hptr->s.prev = pptr;
hptr->s.size = sizep;
hptr->s.h4byte1 = BYTE1;
hptr->s.h4byte2 = BYTE2;
hptr->s.h4byte3 = BYTE3;
hptr->s.h4byte4 = BYTE4;
return ;
}
static void write_footer( struct footer* footp){
footp->f4byte1 = BYTE1; footp->f4byte2 = BYTE2;
footp->f4byte3 = BYTE3; footp->f4byte4 = BYTE4;
return;
}
static union header* getmemory(size_t n){
union header* BigMem = NULL ;
if ( n < INITALLOC ) n = INITALLOC;
if(( BigMem = malloc( n * sizeof(union header))) == NULL )
return NULL;
write_header(BigMem, NULL, NULL, n);
return BigMem;
}
void* my_malloc(char* filename,unsigned int lineno,size_t request){
union header* p = NULL;
union header* q = NULL;
size_t reqblocks = 0;
char* trailer_ptr = NULL;
struct footer* footptr = NULL;
reqblocks = ((request + sizeof(union header) -1)/sizeof(union header))\
+ FOOTERBLOCK + 1 ;
if( !is_table_initialised() ){
initialise_table();
p = getmemory( reqblocks );
if( p == NULL )
return NULL;
else {
if( p->s.size > reqblocks ){
p->s.size = reqblocks;
p->s.next = p + 2 + reqblocks + FOOTERBLOCK ;
}
else
p->s.next = NULL ;
trailer_ptr = (void*)((char*)( p + 1 ) + request);
footptr = (struct footer*) trailer_ptr;
write_footer(footptr);
freep = p + 1 + reqblocks + FOOTERBLOCK ;
write_header(freep, NULL, p + 1,(reqblocks < p->s.size ?\
(p->s.size - reqblocks) : reqblocks));
add_tag(filename,lineno, p, p + 1, request);
return (void*)( p + 1 );
}
}
else {
p = freep;
while( p != NULL && p->s.size < reqblocks ){
q = p;
p = p->s.next;
}
if( p != NULL){
if ( p->s.size > reqblocks ){
p->s.size = reqblocks;
p->s.next = p + 2 + reqblocks + FOOTERBLOCK ;
}
else
p->s.next = NULL ;
trailer_ptr = (void*)((char*)( p + 1 ) + request);
footptr = (struct footer*) trailer_ptr;
write_footer(footptr);
freep = p + 1 + reqblocks + FOOTERBLOCK ;
write_header(freep, NULL, p + 1,(reqblocks < p->s.size ?\
(p->s.size - reqblocks) : reqblocks));
add_tag(filename,lineno, p, p + 1, request);
return (void*)( p + 1 );
}
}
return NULL;
}