标签:
如何自己实现一个动态存储的分配机制,当然有很多的存储的分配方法,关键在于“堆”的管理。



#ifndef DYNAMIC_MALLOC_H#define DYNAMIC_MALLOC_H#define NoFault 0#define OutofMemory 1#define NoRest 2class DynamicMalloc{protected:const static int WSIZE=4;const static int DSIZE=8;const static bool ALLOCED=1;const static bool UNALLOCED=0;private:static char* mem_heap; //指向堆首地址static char* mem_brk; //指向目前分配的“堆”的最后一个字的下一个static char* mem_max_addr; //一直指向最大所能分配的地址,“堆大小”static char* heap_listp; //一直指向序言块const static unsigned int MAX_HEAP=2048;const static unsigned int CHUNKSIZE=30;const static unsigned int MINCHUNK=DSIZE*2+2*WSIZE;unsigned int pack(unsigned int size,unsigned int alloc){return size|alloc;}void put_data(void *ptr,unsigned int val){*((unsigned int*)ptr)=val;}unsigned int get_data(void *ptr){return *((unsigned int*)(ptr));}unsigned int get_size(void *ptr){//取出块大小return get_data(ptr)&(~0x07);}bool get_alloced(void *ptr){//取出“分配”标志return get_data(ptr)&0x01;}char* mem_head(void *ptr){//找到块的头部return (char*)ptr-WSIZE;}char* mem_ftrp(void *ptr){ //找到块的尾部return (char*)ptr+get_size((void*)mem_head(ptr));}char* next_blkb(void *ptr){//找到下一块return (char*)ptr+get_size((void*)mem_head(ptr))+DSIZE;}char *pre_blkb(void *ptr){//找到前面块return (char*)ptr-get_size((void*)((char*)ptr-DSIZE))-DSIZE;}void *mem_sbrk(unsigned int inc);void mm_init();void* extern_heap(unsigned int size);void coalesce(void *ptr);void clearBlock(void *ptr);void* find_fit(unsigned int size);public:int mem_errno;DynamicMalloc();void* mm_malloc(unsigned int size);void mm_free(void *ptr);};#endif
#include<stdio.h>#include<memory>#include<iostream>#include"DynamicMalloc.h"char * DynamicMalloc::heap_listp=NULL;char * DynamicMalloc::mem_heap=NULL;char * DynamicMalloc::mem_brk=NULL;char * DynamicMalloc::mem_max_addr=NULL;DynamicMalloc::DynamicMalloc(){if(mem_heap==NULL){mem_errno=NoFault;mem_heap=(char*)malloc(WSIZE*MAX_HEAP*sizeof(char));if(mem_heap==NULL){mem_errno=OutofMemory;std::cout<<"overflow"<<std::endl;}mem_brk=mem_heap;mem_max_addr=mem_heap+WSIZE*MAX_HEAP*sizeof(char);mm_init();}}void * DynamicMalloc::mem_sbrk(unsigned int inc){if(inc<0||(mem_heap+inc>mem_max_addr)){mem_errno=OutofMemory;std::cout<<"memory overflow!"<<std::endl;return NULL ;}char *old_mem_brk=mem_brk;mem_brk+=inc+DSIZE; //预留空间,用于头和尾return (void*)old_mem_brk;}void DynamicMalloc::mm_init(){if((heap_listp=(char*)mem_sbrk(2*WSIZE))==NULL){return;}put_data(heap_listp,pack(0,ALLOCED));put_data(heap_listp+WSIZE,pack(0,ALLOCED));put_data(heap_listp+2*WSIZE,pack(0,ALLOCED));put_data(heap_listp+3*WSIZE,pack(0,ALLOCED));heap_listp+=2*WSIZE;extern_heap(CHUNKSIZE);}void* DynamicMalloc::extern_heap(unsigned int size){int words=(size%2)? (size+1)*WSIZE:(size)*WSIZE;char *bp=NULL;bp=(char*)mem_sbrk(words);put_data(mem_head(bp),pack(words,UNALLOCED)); //块头put_data(mem_ftrp(bp),pack(words,UNALLOCED)); //块脚put_data(mem_ftrp(bp)+WSIZE,pack(0,ALLOCED)); //新的“堆脚”,也是结束的标志coalesce(bp);return bp;}void DynamicMalloc::clearBlock(void *ptr){char *clear_ptr=(char*)ptr;for(int i=0;i<WSIZE; i++){*(clear_ptr+i)=0;}}void DynamicMalloc::coalesce(void *ptr){bool preAlloced=ALLOCED;bool nxtAlloced=ALLOCED;preAlloced=get_alloced(mem_head(pre_blkb(ptr))); //获得前一块的状态nxtAlloced=get_alloced(mem_head(next_blkb(ptr))); //获得下一块的状态if(preAlloced&&nxtAlloced){//前后两块都分配了return;}else if(preAlloced&&!nxtAlloced){//前一块己分配,后一块没有unsigned int new_size=get_size(mem_head(ptr))+get_size(mem_head(next_blkb(ptr)))+DSIZE;put_data(mem_head(ptr),pack(new_size,UNALLOCED));//设置新块头部put_data(mem_ftrp(ptr),pack(new_size,UNALLOCED)); //新块的脚//clearBlock(mem_ftrp(ptr));//clearBlock(mem_head(next_blkb(ptr))); //清理门户}else if(!preAlloced&&nxtAlloced){//前面的未分配,后面的分配了unsigned int new_size=get_size(mem_head(ptr))+get_size(mem_head(pre_blkb(ptr)))+DSIZE;put_data(mem_head(pre_blkb(ptr)),pack(new_size,UNALLOCED));put_data(mem_ftrp(ptr),pack(new_size,UNALLOCED));//clearBlock(mem_head(ptr));//clearBlock(mem_ftrp(pre_blkb(ptr)));}else if(!preAlloced&&!nxtAlloced){//前后都未分配unsigned int new_size=get_size(mem_head(ptr))+get_size(mem_head(pre_blkb(ptr)))+get_size(mem_head(next_blkb(ptr)));put_data(mem_head(pre_blkb(ptr)), pack(new_size,UNALLOCED));put_data(mem_ftrp(next_blkb(ptr)),pack(new_size,UNALLOCED));//clearBlock(mem_head(ptr));//clearBlock(mem_ftrp(ptr));//clearBlock(mem_ftrp(pre_blkb(ptr)));//clearBlock(mem_head(next_blkb(ptr))); //清理门户}}void* DynamicMalloc::mm_malloc(unsigned int size){unsigned int malloc_size=0;void *reptr=NULL;if(size==0){return NULL;}if(size<=DSIZE){malloc_size=DSIZE;}else{malloc_size=DSIZE*((size+DSIZE+DSIZE-1)/DSIZE);}if((reptr=find_fit(malloc_size))!=NULL){return (void*)reptr;}else{reptr=(void*)extern_heap(malloc_size);put_data(mem_head(reptr),pack(malloc_size,ALLOCED));put_data(mem_ftrp(reptr),pack(malloc_size,ALLOCED));return reptr;}}void* DynamicMalloc::find_fit(unsigned int size){char *ptr=next_blkb(heap_listp); //heap_listp一直指向序言块std::cout<<get_size(mem_head(ptr))<<std::endl;std::cout<<get_alloced(mem_head(ptr))<<std::endl;while(((get_size(mem_head(ptr))!=0)||(get_alloced(mem_head(ptr)))!=ALLOCED)){//从前往后 “首次匹配”std::cout<<get_size(mem_head(ptr))<<std::endl;std::cout<<get_alloced(mem_head(ptr))<<std::endl;if(((get_size(mem_head(ptr))>=size)&&(get_alloced(mem_head(ptr)))==UNALLOCED)){break;;}ptr=next_blkb(ptr);}if(get_alloced(mem_head(ptr))==ALLOCED&&get_size(mem_head(ptr))==0){//没有合适的空间mem_errno=NoRest;return NULL;}else{if(get_size(mem_head(ptr))>=size+MINCHUNK){unsigned int old_size=get_size(mem_head(ptr));put_data(mem_head(ptr),pack(size,ALLOCED)); //待分配块“头”put_data(mem_ftrp(ptr),pack(size,ALLOCED)); //待分配块“尾”put_data(mem_head(next_blkb(ptr)),pack(old_size-size-2*WSIZE,UNALLOCED));put_data(mem_ftrp(next_blkb(ptr)),pack(old_size-size-2*WSIZE,UNALLOCED));return ptr;}else{return ptr;}}}void DynamicMalloc::mm_free(void *ptr){put_data(mem_head(ptr),pack(get_size(mem_head(ptr)),UNALLOCED));put_data(mem_ftrp(ptr),pack(get_size(mem_head(ptr)),UNALLOCED));coalesce(ptr);}
#include "DynamicMalloc.h"#include<iostream>int main(){DynamicMalloc dynamicMalloc;char *ptr=(char*)dynamicMalloc.mm_malloc(10);for(int i=0;i<10;i++){*(ptr+i)=‘a‘;}for(int i=0;i<10;i++){std::cout<<*(ptr+i)<<std::endl;}char* p=(char*)dynamicMalloc.mm_malloc(20);for(int i=0;i<20;i++){*(p+i)=‘a‘;}for(int i=0;i<20;i++){std::cout<<*(p+i)<<std::endl;}char* pp=(char*)dynamicMalloc.mm_malloc(300);dynamicMalloc.mm_free(p);}

void DynamicMalloc::coalesce(void *ptr){bool preAlloced=ALLOCED;bool nxtAlloced=ALLOCED;preAlloced=get_alloced(mem_head(pre_blkb(ptr))); //获得前一块的状态nxtAlloced=get_alloced(mem_head(next_blkb(ptr))); //获得下一块的状态if(preAlloced&&nxtAlloced){//前后两块都分配了return;}else if(preAlloced&&!nxtAlloced){//前一块己分配,后一块没有unsigned int new_size=get_size(mem_head(ptr))+get_size(mem_head(next_blkb(ptr)))+DSIZE;put_data(mem_head(ptr),pack(new_size,UNALLOCED));//设置新块头部put_data(mem_ftrp(ptr),pack(new_size,UNALLOCED)); //新块的脚//clearBlock(mem_ftrp(ptr));//clearBlock(mem_head(next_blkb(ptr))); //清理门户}else if(!preAlloced&&nxtAlloced){//前面的未分配,后面的分配了unsigned int new_size=get_size(mem_head(ptr))+get_size(mem_head(pre_blkb(ptr)))+DSIZE;put_data(mem_head(pre_blkb(ptr)),pack(new_size,UNALLOCED));put_data(mem_ftrp(ptr),pack(new_size,UNALLOCED));//clearBlock(mem_head(ptr));//clearBlock(mem_ftrp(pre_blkb(ptr)));}else if(!preAlloced&&!nxtAlloced){//前后都未分配unsigned int new_size=get_size(mem_head(ptr))+get_size(mem_head(pre_blkb(ptr)))+get_size(mem_head(next_blkb(ptr)));put_data(mem_head(pre_blkb(ptr)), pack(new_size,UNALLOCED));put_data(mem_ftrp(next_blkb(ptr)),pack(new_size,UNALLOCED));//clearBlock(mem_head(ptr));//clearBlock(mem_ftrp(ptr));//clearBlock(mem_ftrp(pre_blkb(ptr)));//clearBlock(mem_head(next_blkb(ptr))); //清理门户}}

static char* mem_heap; //指向堆首地址static char* mem_brk; //指向目前分配的“堆”的最后一个字的下一个static char* mem_max_addr; //一直指向最大所能分配的地址,“堆大小”static char* heap_listp; //一直指向序言块
标签:
原文地址:http://www.cnblogs.com/yml435/p/4690933.html