您的位置:首页 > 其它

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

2016-02-27 20:42 387 查看
本文使用一个全局大数组来模拟物理内存的堆,然后在这个模拟对上进行动态内存分配

代码如下:

#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 struct
struct FreeNode
{
FreeNode *next;
size_t size;
void *mem;
};
// define free list struct
struct 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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  内存分配 malloc 内存