/*
this file implement my own malloc() and free();
the managed memory is a global char array called buf which is 1000 bytes big;
HeadStruct is the data structure used to manage the memory which size is 20 bytes;
in general buf becomes a memory block linklist when inited by calling myInit().
Each block with a HeadStruct head.
myMalloc(size_t size) is used to traverse the whole linklist and find an big enough free block which is
identified by HeadSturct.used==0 && HeadStruct.size>size;
myFree(void *buf) frees the buf block and merge it to its neighbour free blocks if possible;
listBlocks() is used to show the linklist details;
*/
#include <stdio.h>
#define HeadSize (sizeof(HeadStruct))
typedef struct HeadStruct
{
size_t size;
void *buf;
struct HeadStruct *pre,*next;
int used;
}HeadStruct;
char buf[1000];
void myInit();
void *myMalloc(size_t size);
void myFree(void *mem);
void listBlocks();
int main(void)
{
myInit();
int *a = (int *)myMalloc(sizeof(int));
int *b = (int *)myMalloc(sizeof(int));
myFree(a);
myFree(b);
listBlocks();
return 0;
}
void myInit()
{
HeadStruct *p = (HeadStruct*)buf;
p->size = sizeof(buf) - HeadSize;
p->buf = (char*)p + HeadSize;//p should be cast to char*
p->pre = p->next = NULL;
p->used = 0;
}
void listBlocks()
{
HeadStruct *p = (HeadStruct*)buf;
while(p)
{
printf("addr:%d,size:%d,used:%d\n",(char*)(p->buf) - buf,p->size,p->used);
p = p->next;
}
}
void *myMalloc(size_t size)
{
HeadStruct *p = (HeadStruct*)buf;
while(p && p->size < size || p && p->used == 1)
{
p = p->next;
}
if(!p)return NULL;//fail to malloc
if(p->size - size > HeadSize)
{//divide into 2 blocks p and rest;
HeadStruct *rest = (HeadStruct *)((char*)(p->buf)+size);
rest->buf = (char*)rest + HeadSize;//rest should be cast to char*
rest->size = p->size - size - HeadSize;
rest->next = p->next;
if(p->next)
p->next->pre = rest;
p->next = rest;
rest->pre = p;
rest->used = 0;
p->size = size;
}
p->used = 1;
return p->buf;
}
void myFree(void *mem)
{
HeadStruct *actual = (HeadStruct*)((char*)mem - HeadSize);
HeadStruct *tmp;
//printf("actual->size=%d\n",actual->size);
if(!mem || 0 == actual->used)//mem should judged before actual->used
return;
if(actual->next && actual->next->used == 0)
{//merge
actual->size += actual->next->size+HeadSize;//this statement should be before actual->next = tmp
tmp = actual->next->next;
actual->next = tmp;
if(tmp)
tmp->pre = actual;
actual->used = 0;
}
if(actual->pre && actual->pre->used == 0)
{//merge
actual->pre->size += actual->size+HeadSize;
actual->pre->next = actual->next;
if(actual->next)
actual->next->pre = actual->pre;
}
actual->used = 0;
return ;
}
this file implement my own malloc() and free();
the managed memory is a global char array called buf which is 1000 bytes big;
HeadStruct is the data structure used to manage the memory which size is 20 bytes;
in general buf becomes a memory block linklist when inited by calling myInit().
Each block with a HeadStruct head.
myMalloc(size_t size) is used to traverse the whole linklist and find an big enough free block which is
identified by HeadSturct.used==0 && HeadStruct.size>size;
myFree(void *buf) frees the buf block and merge it to its neighbour free blocks if possible;
listBlocks() is used to show the linklist details;
*/
#include <stdio.h>
#define HeadSize (sizeof(HeadStruct))
typedef struct HeadStruct
{
size_t size;
void *buf;
struct HeadStruct *pre,*next;
int used;
}HeadStruct;
char buf[1000];
void myInit();
void *myMalloc(size_t size);
void myFree(void *mem);
void listBlocks();
int main(void)
{
myInit();
int *a = (int *)myMalloc(sizeof(int));
int *b = (int *)myMalloc(sizeof(int));
myFree(a);
myFree(b);
listBlocks();
return 0;
}
void myInit()
{
HeadStruct *p = (HeadStruct*)buf;
p->size = sizeof(buf) - HeadSize;
p->buf = (char*)p + HeadSize;//p should be cast to char*
p->pre = p->next = NULL;
p->used = 0;
}
void listBlocks()
{
HeadStruct *p = (HeadStruct*)buf;
while(p)
{
printf("addr:%d,size:%d,used:%d\n",(char*)(p->buf) - buf,p->size,p->used);
p = p->next;
}
}
void *myMalloc(size_t size)
{
HeadStruct *p = (HeadStruct*)buf;
while(p && p->size < size || p && p->used == 1)
{
p = p->next;
}
if(!p)return NULL;//fail to malloc
if(p->size - size > HeadSize)
{//divide into 2 blocks p and rest;
HeadStruct *rest = (HeadStruct *)((char*)(p->buf)+size);
rest->buf = (char*)rest + HeadSize;//rest should be cast to char*
rest->size = p->size - size - HeadSize;
rest->next = p->next;
if(p->next)
p->next->pre = rest;
p->next = rest;
rest->pre = p;
rest->used = 0;
p->size = size;
}
p->used = 1;
return p->buf;
}
void myFree(void *mem)
{
HeadStruct *actual = (HeadStruct*)((char*)mem - HeadSize);
HeadStruct *tmp;
//printf("actual->size=%d\n",actual->size);
if(!mem || 0 == actual->used)//mem should judged before actual->used
return;
if(actual->next && actual->next->used == 0)
{//merge
actual->size += actual->next->size+HeadSize;//this statement should be before actual->next = tmp
tmp = actual->next->next;
actual->next = tmp;
if(tmp)
tmp->pre = actual;
actual->used = 0;
}
if(actual->pre && actual->pre->used == 0)
{//merge
actual->pre->size += actual->size+HeadSize;
actual->pre->next = actual->next;
if(actual->next)
actual->next->pre = actual->pre;
}
actual->used = 0;
return ;
}