/********************************************************/
未做改进,可能还有BUG
/********************************************************/
#include<stdio.h>
#include<stdlib.h>
#define offsetof(block,member)/
(uint_32)&(((block *)0)->member)
#define HASH_SIZE_C 10000
typedef unsigned int uint_32;
typedef long int l_int;
typedef struct block block;
typedef struct node node;
struct node /* 管理整个数据的结构体*/
{
node *pre;
node *next;
};
struct block
{
int flag; /* 1: used;0:free */
l_int adm_size; /* manage space */
node all; /*用于管理未使用地址*/
l_int next_index;
};
block malloc_header; /* the header of link;*/
void *memery = NULL;
l_int save_size;
l_int *free_hash_table;
l_int *used_hash_table;
int Init_Hash(l_int *hash_table)
{
int i;
l_int *hash_temp = hash_table;
if(hash_temp == NULL) {
printf("hash_table not exist!/n");
exit(1);
} else {
for(i=0; i<HASH_SIZE_C; i++) {
hash_temp[i] = -1;
}
return 1;
}
}
int Free_Hash(l_int adm_size)
{
return (int)( ( adm_size + HASH_SIZE_C - 1 )%HASH_SIZE_C );
};
int Insert_Free_Hash(l_int *free_hash_table,void* addr) // 丢地址,根据size分类;
{
int adm_size_temp;
block *p_addr;
p_addr = (block*)((uint_32)addr - sizeof(block));
if(free_hash_table == NULL) {
printf("the hash_table is not exist!/n");
exit(1);
}
if(addr == 0) {
printf("the address is wrong!/n");
exit(1);
}
adm_size_temp = Free_Hash(p_addr->adm_size);
p_addr->next_index = free_hash_table[adm_size_temp];
free_hash_table[adm_size_temp] = (l_int)addr;
return 1;
}
int Delete_Free_Hash(l_int aq_size,l_int *free_hash_table,void* addr)
{
int size_save;
l_int hash_addr;
l_int addr_front;
int delete_flag = 0;
size_save = Free_Hash(aq_size);
hash_addr = free_hash_table[size_save];
while(hash_addr != -1) {
if(hash_addr == (l_int)addr) {
if(delete_flag == 0) {
free_hash_table[size_save] = ((block*)((uint_32)hash_addr - sizeof(block)))->next_index;
delete_flag = 1;
break;
} else {
((block*)((uint_32)addr_front - sizeof(block)))->next_index = /
((block*)((uint_32)hash_addr - sizeof(block)))->next_index;
}
} else {
addr_front = hash_addr;
hash_addr = ((block*)((uint_32)hash_addr - sizeof(block)))->next_index;
delete_flag = 1;
}
}
if(delete_flag == 0) {
return 0;
} else {
return 1;
}
}
void *Search_Free_Hash(l_int aq_size,l_int *free_hash_table)
{
int size_save;
l_int hash_addr;
block *addr_temp;
block *addr_front;
void *addr = NULL;
int flag_c = 0; /*标记free找到地址 */
int flag_free = 0;
size_save = Free_Hash(aq_size);
while (size_save <= HASH_SIZE_C) {
if(free_hash_table[size_save] == -1) {
size_save++;
} else {
hash_addr = free_hash_table[size_save]; /*存放在hash 表里的FREE 地址*/
while( hash_addr != -1) {
addr_temp = (block*)((uint_32)hash_addr - sizeof(block));
if(addr_temp->adm_size >= aq_size) {
addr_temp ->flag = 1;
if(flag_free == 0) {
free_hash_table[size_save] = addr_temp->next_index;
} else {
addr_front->next_index = addr_temp->next_index;
}
flag_c = 1;
break;
} else {
addr_temp = (block*)((uint_32)hash_addr - sizeof(block)); /* 存放在结构体里的FREE 地址*/
addr_front = addr_temp;
hash_addr = addr_temp->next_index;
flag_free = 1;
}
}
if(flag_c == 1) {
break;
}
size_save++;
}
}
if( flag_c == 0) {
addr = NULL;
} else {
addr = (void *)((uint_32)(addr_temp) + sizeof(block));
}
return addr;
}
l_int Used_Hash( void* addr)
{
return (l_int)( ( (l_int)addr )%HASH_SIZE_C );
};
int Insert_Used_Hash(l_int *used_hash_table,void * addr) // 丢地址,根据addr分类;
{
l_int addr_save;
block *p_addr;
p_addr = (block *)((uint_32)addr - sizeof(block));
if(used_hash_table == NULL) {
printf("the used_hash_table is not exist!/n");
exit(1);
}
if(p_addr == NULL) {
printf("the address is wrong!/n");
exit(1);
}
addr_save = Used_Hash(addr);
p_addr->next_index = used_hash_table[addr_save];
used_hash_table[addr_save] = (l_int)addr;
return 1;
}
int Search_Used_Hash(l_int *used_hash_table,void * addr)
{
int addr_save;
l_int hash_val;
l_int hash_addr;
int used_flag = 0;
int flag_used = 0;
addr_save = Used_Hash(addr);
hash_val = used_hash_table[addr_save];
while(hash_val != -1) {
if(hash_val == (l_int)addr) {
if(used_flag == 0) {
used_hash_table[addr_save] = ((block*)((uint_32)hash_val - sizeof(block)))->next_index;
} else {
((block*)((uint_32)hash_addr - sizeof(block)))->next_index = ((block*)((uint_32)hash_val - sizeof(block)))->next_index;
}
((block*)((uint_32)hash_val - sizeof(block)))->flag = 0;
flag_used = 1;
break;
} else {
hash_addr = hash_val;
hash_val = ((block*)((uint_32)hash_val - sizeof(block)))->next_index;
used_flag = 1;
}
}
return flag_used;
}
void *min_malloc(uint_32 size)
{
void *addr=NULL;
l_int save_free;
l_int *addr_temp;
block *blk=NULL;
block *blk_c=NULL; /* 暂存block;*/
block *blk_new=NULL;
if ( memery == NULL) {
memery = (void *)malloc(size);
if(memery == NULL || size <= sizeof(block)) {
printf("memery error/n");
return addr;
}
blk = (block *)memery;
blk->flag = 0;
blk->all.pre = &(malloc_header.all);
blk->all.next = &(malloc_header.all);
malloc_header.all.pre = &(blk->all); // 初始节点设置
malloc_header.all.next = &(blk->all);
blk->adm_size = size - sizeof(block);
save_size = size;
blk->next_index = -1;
addr = (void *)((uint_32)memery + sizeof(block));
Insert_Free_Hash(free_hash_table,addr);
} else {
addr_temp = (l_int *)Search_Free_Hash(size,free_hash_table) ;
if(addr_temp == NULL) {
printf("there is no enough memery!/n");
exit(1);
} else {
blk = (block *)((uint_32)addr_temp - sizeof(block));
blk->flag = 1;
save_free = blk->adm_size - size; //compare current blk->adm_size with size ,
blk_c = blk;
addr = (void *)((uint_32)blk + sizeof(block));
Insert_Used_Hash(used_hash_table,(l_int *)addr);
blk_new = (block *)((uint_32)blk + size + sizeof(block)); /* 新建的block */
if(blk_new < ((block *)((uint_32)memery + save_size - sizeof(block)) ) || (save_free > sizeof(block))) {
blk_new->flag = 0;
blk_new->adm_size = save_free - sizeof(block);
blk_c->adm_size = size;
blk_new->all.next = blk_c->all.next; // the operate of all;change their pointer.
blk_new->all.pre = &(blk_c->all);
((block *)((uint_32)(blk_c->all.next) - offsetof(block,all)))->all.pre = &(blk_new->all);
blk_c->all.next = &(blk_new->all);
blk_new->next_index = -1;
Insert_Free_Hash(free_hash_table,(l_int *)((uint_32)blk_new + sizeof(block)));
}
}
}
return addr;
}
void min_free(void *p )
{
block *blk = NULL;
block *blk_c = NULL;
block *blk_temp = NULL;
if(Search_Used_Hash(used_hash_table,p) != 1) {
printf("the add is not right!/n");
exit(1);
} else {
blk = (block *)((uint_32)p - sizeof(block));
blk->flag = 0;
blk_c = blk;
if(( ((block *)((uint_32)(blk->all.next) - offsetof(block,all)))->flag != 0) &&
(((block *)((uint_32)(blk->all.pre) - offsetof(block,all)))->flag != 0) ) {
Insert_Free_Hash(free_hash_table,(l_int *)p);
}
else if(( ((block *)((uint_32)(blk->all.next) - offsetof(block,all)))->flag == 0) &&
(((block *)((uint_32)(blk->all.pre) - offsetof(block,all)))->flag != 0) ) {
blk = (block *)((uint_32)(blk_c->all.next) - offsetof(block,all)); // 将block 指向下一个节点;
/* 表示blk节点消亡; */
blk_c->adm_size = blk_c->adm_size + blk->adm_size + sizeof(block);
blk_c->all.next = blk->all.next;
((block *)((uint_32)(blk->all.next)-offsetof(block,all)))->all.pre = &(blk_c->all); // 将当前block的all_link下一个block的all_pre 指向合并后的block;
blk->all.pre = NULL; //
blk->all.next = NULL;
Delete_Free_Hash(blk->adm_size,free_hash_table,(void*)((uint_32)blk + sizeof(block)));
Insert_Free_Hash(free_hash_table,(l_int *)((uint_32)blk_c + sizeof(block)) );
}
else if(( ((block *)((uint_32)(blk->all.next) - offsetof(block,all)))->flag != 0) &&
(((block *)((uint_32)(blk->all.pre) - offsetof(block,all)))->flag == 0) ) {
blk = (block *)((uint_32)(blk_c->all.pre) - offsetof(block,all)); // 将block 指向前一个节点;
/* 表示blk_c节点消亡; */
blk->adm_size = (blk->adm_size + blk_c->adm_size + sizeof(block));
blk->all.next = blk_c->all.next; // 将当前block 的all_next 指向blk_c的下一个block节点? ((block *)((uint_32)(blk_c->all.next) - offsetof(block,all)))->all.pre = &(blk->all);
((block *)((uint_32)(blk_c->all.next)-offsetof(block,all)))->all.pre = &(blk->all);
blk_c->all.next = NULL;
blk_c->all.pre = NULL;
Delete_Free_Hash(blk->adm_size,free_hash_table,(void *)((uint_32)blk + sizeof(block)));
Insert_Free_Hash(free_hash_table,(l_int *)((uint_32)blk + sizeof(block)));
}
else if((((block *)( (uint_32)(blk->all.next) - offsetof(block,all))) ->flag == 0)&&
(((block *)((uint_32)(blk->all.pre) - offsetof(block,all)))->flag == 0) ) {
blk = (block *)((uint_32)(blk_c->all.pre)-offsetof(block,all));
blk_temp = (block *)((uint_32)(blk_c->all.next)-offsetof(block,all));
blk->adm_size = blk->adm_size + blk_c->adm_size + blk_temp->adm_size + sizeof(block) + sizeof(block);
/* 被合并节点消亡 */
blk->all.next = blk_temp->all.next;
((block *)((uint_32)(blk_temp->all.next)-offsetof(block,all)))->all.pre = &(blk->all);
blk_c->all.pre = NULL;
blk_c->all.next = NULL;
blk_temp->all.pre = NULL;
blk_temp->all.next = NULL;
Delete_Free_Hash(blk->adm_size,free_hash_table,(void *)((uint_32)blk + sizeof(block)));
Delete_Free_Hash(blk_temp->adm_size,free_hash_table,(void *)((uint_32)blk_temp + sizeof(block)));
Insert_Free_Hash(free_hash_table,(l_int *)((uint_32)blk + sizeof(block)));
}
}
}
************** ///
void show_all(void)
{
block *p;
node *q;
p = (block *)((uint_32)(malloc_header.all.next)-offsetof(block,all));
q = p->all.next;
printf("all:/n/n");
while(q != &(malloc_header.all)) {
printf("flag=:%d/tsize=:%d/n",p->flag,p->adm_size);
p = (block *)((uint_32)(p->all.next)-offsetof(block,all));
q = p->all.next;
}
printf("flag=:%d/tsize=:%d/n",p->flag,p->adm_size);
}
int main()
{
block *addr=NULL;
block *addr_1=NULL;
block *addr_2=NULL;
free_hash_table = (uint_32 *)malloc(sizeof(int)*HASH_SIZE_C);
used_hash_table = (uint_32 *)malloc(sizeof(int)*HASH_SIZE_C);
malloc_header.flag = 1;
Init_Hash(used_hash_table);
Init_Hash(free_hash_table);
addr=(block *) min_malloc(1048576);
printf("初始化地址:%d/n",addr);
addr=(block *)min_malloc(1024);
printf("第1次 申请使用的地址:%d/n",addr);
show_all();
addr_1=(block *)min_malloc(1024);
printf("第2次 申请使用的地址:%d/n",addr_1);
show_all();
addr_2=(block *)min_malloc(1024);
printf("第3次 申请使用的地址:%d/n",addr_2);
show_all();
min_free(addr);
addr = NULL;
show_all();
min_free(addr_2);
addr_2=NULL;
show_all();
min_free(addr_1);
addr_1=NULL;
show_all();
addr=min_malloc(1);
printf("第4次 申请使用的地址:%d/n",addr);
show_all();
addr_1=(block *)min_malloc(2048);
printf("第5次 申请使用的地址:%d/n",addr_1);
show_all();
addr_2=(block *)min_malloc(2048);
printf("第6次 申请使用的地址:%d/n",addr_2);
show_all();
min_free(addr_1);
addr_1=NULL;
show_all();
addr_1=(block *)min_malloc(2048);
printf("第7次 申请使用的地址:%d/n",addr_1);
show_all();
min_free(addr_2);
addr_2 = NULL;
show_all();
min_free(addr);
addr=NULL;
show_all();
return 0;
}