#include<sys/types.h>
#include<stdlib.h>
#include "malloc.h"
#include<iostream>
#include<unistd.h>
using namespace std;
#define BLOCK_SIZE 32
typedef struct s_block *t_block;
s_block *first_block=NULL;
struct s_block//控制塊
{
size_t size;//大小
t_block prev;//前邊
t_block next;//後邊
int free;//是否可用
int padding;//填充
//char data[1];
};
t_block seek_block(t_block *last, size_t size)//找一個滿足要求的塊
{
t_block b = first_block;
// cout<<&(*first_block)<<endl;
//cout<<&(*b)<<endl;
while(b)
{
cout<<"b's size is:"<<b->size<<endl<<"seek size is:"<<size<<" is free:"<<b->free<<endl;;
if((b->free==1) &&(b->size >= size))//free and big enough
{
break;
}
else
{
*last = b;
b = b->next;
}
}
return b;
}
t_block expand_heap(t_block last, size_t s)//開新的空間
{
t_block b;
b = (t_block)sbrk(0);//sbrk得到沒有映射的虛擬地址
//cout<<BLOCK_SIZE + s<<endl;
if(sbrk(BLOCK_SIZE + s) == (void *)-1)//sbrk 失敗, return null;
{
return NULL;
}
b->size = s;
b->next = NULL;
if(last)//link to the last block
{
last->next = b;
}
b->free = 0;
return b;
}
void fenge_block(t_block b, size_t s)
{
t_block mnew;
mnew = (t_block)(b+BLOCK_SIZE)+s;
mnew->size = b->size - s - BLOCK_SIZE;
mnew->next = b->next;
b->next->prev=mnew;
mnew->prev=b;
mnew->free = 1;
b->size -= s;
b->next = mnew;
}
size_t duiqi(size_t s)
{
if((s & 0x7) == 0)
return s;
return ((s >> 3) + 1) << 3;
}
//整合前面的函數 實現一個malloc功能:
void *mmalloc(size_t size)
{
t_block b;
t_block last;
size_t s;
//cout<<size<<endl;
s = duiqi(size);
if(first_block)//以前申請過空間
{
last = first_block;
b = seek_block(&last, s);//先從用過的空間裏找有沒有可重複利用的
if(b)
{
if ((b->size - s) >= ( BLOCK_SIZE + 8))//如果找到了可用的塊,但是空間太大,就可以切割一下
fenge_block(b, s);
b->free = 0;
}
else//沒找到就去開闢新的空間
{
b = expand_heap(last, s);
if(!b)//開闢失敗
return NULL;
}
}
else//以前沒申請過空間
{
b = expand_heap(NULL, s);
if(!b)
return NULL;
first_block = b;//現在b就是firstblock
//cout<<"extend first_block size is"<<first_block->size<<endl;
//cout<<"extend first_block address is"<<&first_block->size<<endl;
}
// cout<<"extend b size is"<<b->size<<endl;
//cout<<"extend b address is"<<&b->size<<endl;
// return b->a;
void *p=(void *)b;
p+=BLOCK_SIZE;
return p;
}
t_block hebing(t_block b)//某個空間不用的時候,看前後有沒有空閒空間,有的話就合在一起
{
t_block t=b;
cout<<"fusion "<<t<<" "<<t->size<<endl;
if (b->next && b->next->free)
{
b->size += BLOCK_SIZE + b->next->size;
b->next = b->next->next;
b->next->prev = b;
}
if(b->prev&&b->prev->free)
{
b->size+=BLOCK_SIZE+b->prev->size;
b->prev->next=b->next;
b->next->prev=b->prev;
b=b->prev;
}
return b;
}
void mfree(void *p)
{
//cout<<endl<<"This is free\n"<<endl<<endl;
s_block * b;
p=p-BLOCK_SIZE;
b = (s_block *)(p);
//cout<<b<<endl;
b=hebing(b);//先跟自己前後的空間看要不要合併
b->free = 1;
//cout<<(b->free)<<" "<<(b->size)<<endl;
}
int main()
{
cout<<sizeof(s_block)<<endl;
//cout<<sizeof(int)<<" "<<sizeof(size_t)<<endl<<sizeof(t_block)<<" "<<sizeof(s_block)<<endl;
int* data = (int*)mmalloc(2*sizeof(int));
cout<<data<<endl;
*data=1;
cout<<*data<<endl;
//cout<<"address:"<<&(*first_block)<<endl;
//cout<<"size:"<<first_block->size<<endl;
int* data2 = (int*)mmalloc(2*sizeof(int));
cout<<data2<<endl;
*data2=2;
cout<<*data2<<endl;
//cout<<"address:"<<&(*first_block)<<endl;
//cout<<"size"<<first_block->size<<endl;
mfree(data);
mfree(data2);
int* data3= (int*)mmalloc(sizeof(int));
cout<<data3<<endl;
*data3=3;
cout<<*data3<<endl;
int* data4= (int*)mmalloc(sizeof(int));
cout<<data4<<endl;
*data4=4;
cout<<*data4<<endl;
mfree(data3);
mfree(data4);
// int* data1=(int*)malloc(size);
// cout<<data1<<endl;
return 0;
}