Linux下實現malloc函數

#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;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章