申请栈空间,实现initMallocPoll、mAlloc、mRealloc、mFree动态分配。
使用blk结构体记录空间分配,返回申请空间的地址在紧跟在blk后,链表记录已分配或未分配的块,申请或释放时,改变链表指针的指向,合并相邻未分配块。
本篇文章参考自 https://blog.csdn.net/wxx258369/article/details/78949687,仅仅对其中的一部分做了修改
代码
mAlloc.h
1 2 3 4 5 6 7 8 9 10 11 12 13
| #ifndef __mAlloc_h__ #define __mAlloc_h__
void initMallocPool(void *pool, unsigned size);
void* mAlloc(unsigned size);
void* mRealloc(void *ptr, unsigned size);
void mFree(void *ptr);
#endif
|
mAlloc.c
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
| #include "mAlloc.h" #include <string.h>
typedef struct _blk { unsigned size; struct _blk *next; }blk, *pblk;
static pblk phead = NULL;
void initMallocPool(void *pool, unsigned size) { phead = (pblk)pool; phead->next = NULL; phead->size = size - sizeof(blk); }
void* mAlloc(unsigned size) { pblk pNext,pNode; void *result; pNext = phead; if((size&3) != 0) size = ((size >> 2) + 1) << 2; do { if(pNext->size >= size + sizeof(blk)) { pNext->size = pNext->size - size - sizeof(blk); pNode = (pblk)((void*)pNext + pNext->size + sizeof(blk)); pNode->size = size; result = (void*)(++pNode); return result; } pNext = pNext->next; }while(pNext != NULL); return NULL; }
void merge(pblk pPrior, pblk pNext) { if(pNext == (pblk)((void*)pPrior + pPrior->size + sizeof(blk))) { pPrior->size += pNext->size + sizeof(blk); pPrior->next = pNext->next; } }
void mFree(void *ptr) { pblk pFree = (pblk)(ptr - sizeof(blk)); pblk pNext = phead; pblk pPrior = phead; do { pPrior = pNext; pNext = pNext->next; if(pNext == NULL || (pPrior <= pFree && pNext >= pFree)) { pFree->next = pNext; pPrior->next = pFree; break; } }while(pNext != NULL); merge(pPrior, pFree); merge(pFree, pNext); merge(pPrior, pNext); }
void* mRealloc(void *ptr, unsigned size) { if(ptr == NULL) return mAlloc(size); pblk pFree = (pblk)(ptr - sizeof(blk)); void *p = mAlloc(size); if(p != NULL) { memset(p, 0, size); if(pFree->size < size) size的大小不总大于原空间的大小 memcpy(p, ptr, pFree->size); else memcpy(p, ptr, size); mFree(ptr); return p; } return NULL; }
|
测试
1 2 3 4 5 6 7 8 9 10
| #include "mAlloc.h"
int main() { char pool[1024*5]; initMallocPool(pool, sizeof(pool)); char *t = mAlloc(100); mFree(t); return 0; }
|
改进
mAlloc可以进行优化,寻找所有未分配块中最接近需要size大小的块,避免剩余空间很多,但过于零碎,在需要分配一大块完整空间时找不到。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| void* mAlloc(unsigned size) { pblk pNext,pNode; void *result; pNext = phead; pblk pMin = phead; if((size&3) != 0) size = ((size >> 2) + 1) << 2; do { if(pNext->size >= size + sizeof(blk)) { if(pMin->size > pNext->size) pMin = pNext; } pNext = pNext->next; }while(pNext != NULL); if(pMin->size >= size + sizeof(blk)) { pMin->size = pMin->size - size - sizeof(blk); pNode = (pblk)((void*)pMin + pMin->size + sizeof(blk)); pNode->size = size;
result = (void*)(++pNode); return result; } return NULL; }
|