#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;
}
//整合前面的函数 实现一个malloc功能:
void *mmalloc(size_t size)
{
t_block b;
t_block last;
size_t s;
//cout<<size<<endl;
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;
}