模拟malloc - free 函数动态分配内存

来源:互联网 发布:辐射4室内光源优化 编辑:程序博客网 时间:2024/06/04 23:20

本文使用一个全局大数组来模拟物理内存的堆,然后在这个模拟对上进行动态内存分配
代码如下:

#include <iostream>#include <stdlib.h>#include <stdio.h>using namespace std;#define MEM_POOL_SIZE (2048)char memPool[MEM_POOL_SIZE] = {0};#define NODE_HEAD_SIZE sizeof(FreeNode)#define TRUE    (1)#define FALSE   (0)// define free node structstruct FreeNode{    FreeNode *next;    size_t size;    void *mem;};// define free list structstruct FreeList{    size_t freeNodeNum;    FreeNode *head; };static int CanMerge(FreeNode *pre, FreeNode *next){    printf("%d --- > %d \n", pre, next);    if ((pre->mem + pre->size) == (void *)next)    {        return TRUE;    }    return FALSE;}static FreeNode * MergeFreeNode(FreeNode *pre, FreeNode *next){    pre->next = next->next;    pre->size = pre->size + NODE_HEAD_SIZE + next->size;    return pre;}void FreeList_Init(FreeList *freeList){    FreeNode *temp;    freeList->freeNodeNum = 1;    temp = (FreeNode *)memPool;    temp->size = MEM_POOL_SIZE - sizeof(FreeNode);    temp->mem = (void *)memPool + sizeof(FreeNode);    temp->next = NULL;    freeList->head = temp;}void * FreeList_Alloc(FreeList *freeList, size_t size){    FreeNode *curNode, *preNode;    void *retPtr;    void *reserveMem;    FreeNode *reserveNode;    // deal with head node case    if (freeList->head->size == size)    {        retPtr = freeList->head->mem;        freeList->head = freeList->head->next;        return retPtr;    }    if (freeList->head->size > size)    {        retPtr = freeList->head->mem;        reserveMem = (void *)(freeList->head) + sizeof(FreeNode) + size;        reserveNode = (FreeNode *)reserveMem;        reserveNode->size = freeList->head->size - size - sizeof(FreeNode);        reserveNode->next = freeList->head->next;        reserveNode->mem = reserveMem + sizeof(FreeNode);        freeList->head->size = size;        freeList->head = reserveNode;        return retPtr;    }    preNode = freeList->head;    curNode = freeList->head->next;    while (curNode)    {        if (curNode->size == size)         {            // start alloc            preNode->next = curNode->next;            return curNode->mem;        }        if (curNode->size > size)        {            // star alloc            retPtr = curNode->mem;            reserveMem = (void *)(curNode) + sizeof(FreeNode) + size;            reserveNode = (FreeNode *)reserveMem;            reserveNode->size = curNode->size - size - sizeof(FreeNode);            reserveNode->next = curNode->next;            reserveNode->mem = reserveMem + sizeof(FreeNode);            preNode->next = reserveNode;            curNode->size = size;            return retPtr;        }        preNode = curNode;        curNode = curNode->next;    }    return NULL;}void FreeList_Free(FreeList *freeList, void *mem){    FreeNode *curNode, *preNode;    FreeNode *headPtr = freeList->head;    FreeNode *freePtr = (FreeNode *)(mem - sizeof(FreeNode));    // first node     if (mem < headPtr->mem)    {        // if merge ?        if (CanMerge(freePtr, headPtr))        {            freeList->head = MergeFreeNode(freePtr, headPtr);        }        else        {            freePtr->next = headPtr;            freeList->head = freePtr;        }    }    preNode = freeList->head;    curNode = freeList->head->next;    while (curNode)    {        if (mem < curNode->mem)        {            if (CanMerge(preNode, freePtr))            {                MergeFreeNode(preNode, freePtr);                if (CanMerge(preNode, curNode))                {                    MergeFreeNode(preNode, curNode);                }            }            else            {                // don't merge pre                FreeNode *tmp = preNode->next;                preNode->next = freePtr->next;                freePtr->next = tmp;                if (CanMerge(freePtr, curNode))                {                    // MergeFreeNode(f)                    preNode->next = MergeFreeNode(freePtr, curNode);                }            }            break;        }        preNode = curNode;        curNode = curNode->next;    }}void FreeList_Print(FreeList *freeList){    printf("\n------------------------start\n");    FreeNode *h = freeList->head;    while (h)    {        // print current node info        printf("NodeAddr %d   MemSize %d\n", h, h->size);        h = h->next;    }    printf("\n------------------------end\n");}/* run this program using the console pauser or add your own getch, system("pause") or input loop */int main(int argc, char** argv) {    cout << "dynamic memory alloc test start ... " << endl;    FreeList fl;    FreeList_Init(&fl);    FreeList_Print(&fl);    // test alloc     char *testArr = (char *)FreeList_Alloc(&fl, 100);    FreeList_Print(&fl);    // test realloc     char *testArr1 = (char *)FreeList_Alloc(&fl, 100);    FreeList_Print(&fl);    //char *testArr2 = (char *)FreeList_Alloc(&fl, 100);    //FreeList_Print(&fl);    printf("free ----------- \n");    FreeList_Free(&fl, testArr);    char *testArr3 = (char *)FreeList_Alloc(&fl, 50);    char *testArr4 = (char *)FreeList_Alloc(&fl, 200);    FreeList_Free(&fl, testArr4);    FreeList_Free(&fl, testArr3);    FreeList_Print(&fl);    printf("dynamic memory alloc test end   ... \n");    getchar();    return 0;}
0 0
原创粉丝点击