注:这篇博客主要讲了我用C语言实现静态内存池管理的算法和思想。首先建立这些内存块的结构体索引。然后用malloc申请我们需要管理的内存块。在申请好的内存池里,进行内存使用。申请用户需要的内存,用的是轮询的方式,根据内存块的大小在几种不同的内存块中依次查找是否被使用的标志。申请、释放内存操作就是改变每块内存的flag。在程序结束后,free全部的内存,销毁内存池。我暂时还想不到更快的方法来申请内存,因为申请释放内存的操作不是有序进行的,所以要使用轮询的方式。总而言之,思想最重要,无论算法还是数据结构都是一种解决问题的思想。我们可以借鉴常用的链表、树、图等数据结构,但也不必拘泥于它的形式,可以适当进行变换。欢迎大家参考和指导。
64字节的内存块数量100块
256字节的内存块数量50块
1024字节的内存块数量10块
4096字节的内存块数量3块
实现要求(给出函数原型,请大家实现函数体):
内存池初始化函数:int initMem(void),返回1成功,其他值失败
内存块申请函数:void *getMem(unsigned int size),成功返回内存块地址,失败返回NULL
内存块释放函数:int retMem(void *buf),返回1成功,其他值失败
内存池统计函数:void showMem(void),各内存当前申请数、释放数、成功失败情况统计,用printf输出显示即可
验证用测试用例(最低要求):
1、把32字节的内存块全部申请完->接着归还一块->再申请一块->全部释放完。要求showMem显示结果正确!
2、4096字节内存块全部申请再全部释放
3、5000字节内存块申请
4、所有提供的内存(各种大小)全部申请完,再全部释放完
静态内存池管理要求:
32字节的内存块数量100块64字节的内存块数量100块
256字节的内存块数量50块
1024字节的内存块数量10块
4096字节的内存块数量3块
实现要求(给出函数原型,请大家实现函数体):
内存池初始化函数:int initMem(void),返回1成功,其他值失败
内存块申请函数:void *getMem(unsigned int size),成功返回内存块地址,失败返回NULL
内存块释放函数:int retMem(void *buf),返回1成功,其他值失败
内存池统计函数:void showMem(void),各内存当前申请数、释放数、成功失败情况统计,用printf输出显示即可
验证用测试用例(最低要求):
1、把32字节的内存块全部申请完->接着归还一块->再申请一块->全部释放完。要求showMem显示结果正确!
2、4096字节内存块全部申请再全部释放
3、5000字节内存块申请
4、所有提供的内存(各种大小)全部申请完,再全部释放完
5、申请一块32字节,对该内存块释放两次
#ifndef __MEMORY_POLL_H__
#define __MEMORY_POLL_H__
#define true 1
#define false 0
//定义内存块
struct Mem_Chunk {
int num;
int size;
};
//定义内存池
struct Mem_Pool {
struct Mem_Chunk *MemChunk32;
struct Mem_Chunk *MemChunk64;
struct Mem_Chunk *MemChunk256;
struct Mem_Chunk *MemChunk1024;
struct Mem_Chunk *MemChunk4096;
};
typedef struct p_Mem_Block_32 {
char data[32];
char flag; //use or not
char *next;
}p_Mem_Block_32;
typedef struct p_Mem_Block_64 {
char data[64];
char flag; //use or not
char *next;
}p_Mem_Block_64;
typedef struct p_Mem_Block_256 {
char data[256];
char flag; //use or not
char *next;
}p_Mem_Block_256;
typedef struct p_Mem_Block_1024 {
char data[1024];
char flag; //use or not
char *next;
}p_Mem_Block_1024;
typedef struct p_Mem_Block_4096 {
char data[4096];
char flag; //use or not
char *next;
}p_Mem_Block_4096;
extern int initMem(void);
extern void *getMem(unsigned int size);
extern int retMem(void *buf);
extern void showMem(void);
extern int freeMem(void);
#endif
#include
#include
#include
#include "memory_pool.h"
//初始化内存块的大小、数量
struct Mem_Chunk MemChunk32 = {100, 32};
struct Mem_Chunk MemChunk64 = {100, 64};
struct Mem_Chunk MemChunk256 = {50, 256};
struct Mem_Chunk MemChunk1024 = {10, 1024};
struct Mem_Chunk MemChunk4096 = {3, 4096};
struct Mem_Pool MemPool = {&MemChunk32, &MemChunk64, &MemChunk256, &MemChunk1024, &MemChunk4096};
p_Mem_Block_32 *Block_32_Node = NULL;
p_Mem_Block_64 *Block_64_Node = NULL;
p_Mem_Block_256 *Block_256_Node = NULL;
p_Mem_Block_1024 *Block_1024_Node = NULL;
p_Mem_Block_4096 *Block_4096_Node = NULL;
int Block_32_Node_Init(struct Mem_Chunk MemChunk32)
{
char i;
p_Mem_Block_32 *pBlock_32 = NULL;
for(i = 0; i < MemChunk32.num; i++)
{
Block_32_Node = (p_Mem_Block_32 *)malloc(sizeof(p_Mem_Block_32));
if(NULL == Block_32_Node) return false;
memset(Block_32_Node, 0, sizeof(p_Mem_Block_32));
Block_32_Node ->next = pBlock_32;
pBlock_32 = Block_32_Node;
}
return true;
}
int Block_64_Node_Init(struct Mem_Chunk MemChunk64)
{
char i;
p_Mem_Block_32 *pBlock_64 = NULL;
for(i = 0; i < MemChunk64.num; i++)
{
Block_64_Node = (p_Mem_Block_64 *)malloc(sizeof(p_Mem_Block_64));
if(NULL == Block_64_Node) return false;
memset(Block_64_Node, 0, sizeof(p_Mem_Block_64));
Block_64_Node ->next = pBlock_64;
pBlock_64 = Block_64_Node;
}
return true;
}
int Block_256_Node_Init(struct Mem_Chunk MemChunk256)
{
char i;
p_Mem_Block_256 *pBlock_256 = NULL;
for(i = 0; i < MemChunk256.num; i++)
{
Block_256_Node = (p_Mem_Block_256 *)malloc(sizeof(p_Mem_Block_256));
if(NULL == Block_256_Node) return false;
memset(Block_256_Node, 0, sizeof(p_Mem_Block_256));
Block_256_Node ->next = pBlock_256;
pBlock_256 = Block_256_Node;
}
return true;
}
int Block_1024_Node_Init(struct Mem_Chunk MemChunk1024)
{
char i;
p_Mem_Block_1024 *pBlock_1024 = NULL;
for(i = 0; i < MemChunk1024.num; i++)
{
Block_1024_Node = (p_Mem_Block_1024 *)malloc(sizeof(p_Mem_Block_1024));
if(NULL == Block_1024_Node) return false;
memset(Block_1024_Node, 0, sizeof(p_Mem_Block_1024));
Block_1024_Node ->next = pBlock_1024;
pBlock_1024 = Block_1024_Node;
}
return true;
}
int Block_4096_Node_Init(struct Mem_Chunk MemChunk4096)
{
char i;
p_Mem_Block_4096 *pBlock_4096 = NULL;
for(i = 0; i < MemChunk4096.num; i++)
{
Block_4096_Node = (p_Mem_Block_4096 *)malloc(sizeof(p_Mem_Block_4096));
if(NULL == Block_4096_Node) return false;
memset(Block_4096_Node, 0, sizeof(p_Mem_Block_4096));
Block_4096_Node ->next = pBlock_4096;
pBlock_4096 = Block_4096_Node;
}
return true;
}
//用malloc申请内存,并将地址赋给定义的内存块结构体变量
int initMem(void)
{
if(!Block_32_Node_Init(MemChunk32))return false;
if(!Block_64_Node_Init(MemChunk64))return false;
if(!Block_256_Node_Init(MemChunk256))return false;
if(!Block_1024_Node_Init(MemChunk1024))return false;
if(!Block_4096_Node_Init(MemChunk4096))return false;
printf("Memory Initialize Successfully!\n");
return true;
}
void *getMem(unsigned int size)
{
int i;
p_Mem_Block_32 *pBlock_32_Node = Block_32_Node;
p_Mem_Block_64 *pBlock_64_Node = Block_64_Node;
p_Mem_Block_256 *pBlock_256_Node = Block_256_Node;
p_Mem_Block_1024 *pBlock_1024_Node = Block_1024_Node;
p_Mem_Block_4096 *pBlock_4096_Node = Block_4096_Node;
if(size > 4096) return NULL;
if(size > 1024)
{
for(i = 0; i < MemChunk4096.num; i++)
{
if(pBlock_4096_Node == NULL)return pBlock_4096_Node;
if(pBlock_4096_Node ->flag == 1)
{
pBlock_4096_Node = pBlock_4096_Node->next;
continue;
}
if(pBlock_4096_Node ->flag == 0)
{
pBlock_4096_Node ->flag = 1;
return pBlock_4096_Node;
}
}
return NULL;
}
if(size > 256)
{
for(i = 0; i < MemChunk1024.num; i++)
{
if(pBlock_1024_Node == NULL)return pBlock_1024_Node;
if(pBlock_1024_Node ->flag == 1)
{
pBlock_1024_Node = pBlock_1024_Node->next;
continue;
}
if(pBlock_1024_Node ->flag == 0)
{
pBlock_1024_Node ->flag = 1;
return pBlock_1024_Node;
}
}
return NULL;
}
if(size > 64)
{
for(i = 0; i < MemChunk256.num; i++)
{
if(pBlock_256_Node == NULL)return pBlock_256_Node;
if(pBlock_256_Node ->flag == 1)
{
pBlock_256_Node = pBlock_256_Node->next;
continue;
}
if(pBlock_256_Node ->flag == 0)
{
pBlock_256_Node ->flag = 1;
return pBlock_256_Node;
}
}
return NULL;
}
if(size > 32)
{
for(i = 0; i < MemChunk64.num; i++)
{
if(pBlock_64_Node == NULL)return pBlock_64_Node;
if(pBlock_64_Node ->flag == 1)
{
pBlock_64_Node = pBlock_64_Node->next;
continue;
}
if(pBlock_64_Node ->flag == 0)
{
pBlock_64_Node ->flag = 1;
return pBlock_64_Node;
}
}
return NULL;
}
if(size > 0)
{
for(i = 0; i < MemChunk32.num; i++)
{
if(pBlock_32_Node == NULL)return pBlock_32_Node;
if(pBlock_32_Node ->flag == 1)
{
pBlock_32_Node = pBlock_32_Node->next;
continue;
}
if(pBlock_32_Node ->flag == 0)
{
pBlock_32_Node ->flag = 1;
return pBlock_32_Node;
}
}
return NULL;
}
return NULL;
}
int retMem(void *buf)
{
int i;
p_Mem_Block_32 *pBlock_32_Node = Block_32_Node;
p_Mem_Block_64 *pBlock_64_Node = Block_64_Node;
p_Mem_Block_256 *pBlock_256_Node = Block_256_Node;
p_Mem_Block_1024 *pBlock_1024_Node = Block_1024_Node;
p_Mem_Block_4096 *pBlock_4096_Node = Block_4096_Node;
for(i = 0; i < MemChunk4096.num; i++)
{
if(pBlock_4096_Node == buf)
{
pBlock_4096_Node ->flag = 0;
return true;
}
pBlock_4096_Node = pBlock_4096_Node->next;
}
for(i = 0; i < MemChunk1024.num; i++)
{
if(pBlock_1024_Node == buf)
{
pBlock_1024_Node ->flag = 0;
return true;
}
pBlock_1024_Node = pBlock_1024_Node->next;
}
for(i = 0; i < MemChunk256.num; i++)
{
if(pBlock_256_Node == buf)
{
pBlock_256_Node ->flag = 0;
return true;
}
pBlock_256_Node = pBlock_256_Node->next;
}
for(i = 0; i < MemChunk64.num; i++)
{
if(pBlock_64_Node == buf)
{
pBlock_64_Node ->flag = 0;
return true;
}
pBlock_64_Node = pBlock_64_Node->next;
}
for(i = 0; i < MemChunk32.num; i++)
{
if(pBlock_32_Node == buf)
{
pBlock_32_Node ->flag = 0;
return true;
}
pBlock_32_Node = pBlock_32_Node->next;
}
return false;
}
void showMem(void)
{
int i = 0;
int request_number = 0;
int free_number = 0;
p_Mem_Block_32 *pBlock_32_Node = Block_32_Node;
p_Mem_Block_64 *pBlock_64_Node = Block_64_Node;
p_Mem_Block_256 *pBlock_256_Node = Block_256_Node;
p_Mem_Block_1024 *pBlock_1024_Node = Block_1024_Node;
p_Mem_Block_4096 *pBlock_4096_Node = Block_4096_Node;
for(i = 0; i < MemChunk32.num; i++)
{
if(pBlock_32_Node ->flag == 1)request_number++;
else free_number++;
pBlock_32_Node = pBlock_32_Node->next;
}
printf("The Memory_Chunk_32 pMemBlock32 number: %d\n", MemChunk32.num);
printf("request_number: %d free_number: %d\n",request_number, free_number);
request_number = 0;
free_number = 0;
for(i = 0; i < MemChunk64.num; i++)
{
if(pBlock_64_Node ->flag == 1)request_number++;
else free_number++;
pBlock_64_Node = pBlock_64_Node->next;
}
printf("The Memory_Chunk_64 pMemBlock64 number: %d\n", MemChunk64.num);
printf("request_number: %d free_number: %d\n",request_number, free_number);
request_number = 0;
free_number = 0;
for(i = 0; i < MemChunk256.num; i++)
{
if(pBlock_256_Node ->flag == 1)request_number++;
else free_number++;
pBlock_256_Node = pBlock_256_Node->next;
}
printf("The Memory_Chunk_256 pMemBlock256 number: %d\n", MemChunk256.num);
printf("request_number: %d free_number: %d\n",request_number, free_number);
request_number = 0;
free_number = 0;
for(i = 0; i < MemChunk1024.num; i++)
{
if(pBlock_1024_Node ->flag == 1)request_number++;
else free_number++;
pBlock_1024_Node = pBlock_1024_Node->next;
}
printf("The Memory_Chunk_1024 pMemBlock1024 number: %d\n", MemChunk1024.num);
printf("request_number: %d free_number: %d\n",request_number, free_number);
request_number = 0;
free_number = 0;
for(i = 0; i < MemChunk4096.num; i++)
{
if(pBlock_4096_Node ->flag == 1)request_number++;
else free_number++;
pBlock_4096_Node = pBlock_4096_Node->next;
}
printf("The Memory_Chunk_4096 pMemBlock4096 number: %d\n", i);
printf("request_number: %d free_number: %d\n",request_number, free_number);
}
//销毁内存池,将申请的内存全部释放掉。
int freeMem(void)
{
int i;
p_Mem_Block_32 *pBlock_32_Node = Block_32_Node;
p_Mem_Block_64 *pBlock_64_Node = Block_64_Node;
p_Mem_Block_256 *pBlock_256_Node = Block_256_Node;
p_Mem_Block_1024 *pBlock_1024_Node = Block_1024_Node;
p_Mem_Block_4096 *pBlock_4096_Node = Block_4096_Node;
for(i = 0; i < MemChunk32.num; i++)
{
pBlock_32_Node = Block_32_Node;
free(Block_32_Node);
Block_32_Node = pBlock_32_Node ->next;
}
for(i = 0; i < MemChunk64.num; i++)
{
pBlock_64_Node = Block_64_Node;
free(Block_64_Node);
Block_64_Node = pBlock_64_Node ->next;
}
for(i = 0; i < MemChunk256.num; i++)
{
pBlock_256_Node = Block_256_Node;
free(Block_256_Node);
Block_256_Node = pBlock_256_Node ->next;
}
for(i = 0; i < MemChunk1024.num; i++)
{
pBlock_1024_Node = Block_1024_Node;
free(Block_1024_Node);
Block_1024_Node = pBlock_1024_Node ->next;
}
for(i = 0; i < MemChunk4096.num; i++)
{
pBlock_4096_Node = Block_4096_Node;
free(Block_4096_Node);
Block_4096_Node = pBlock_4096_Node ->next;
}
printf("Memory Freed Successfully!\n");
return true;
}
#include
#include "memory_pool.h"
int test1(void)
{
int i, j;
char *pBlock[100];
for(i = 0; i < 100; i++)
{
pBlock[i] = (char*)getMem(32);
if(pBlock[i] == NULL){
printf("Error: The request of Block[%d] failed!\n", i);
return false;
}
}
showMem();
if(retMem(pBlock[99]))
{
printf("The 100th Block is freed.\n");
}else
{
printf("Error: The 100th Block can't be freed!\n");
return false;
}
showMem();
pBlock[99] = (char*)getMem(32);
if(pBlock[99] == NULL){
printf("Error: The request of Block[99] failed!\n");
return false;
}
showMem();
for(i = 99; i >= 0; i--)
{
retMem(pBlock[i]);
}
showMem();
return 0;
}
int test2(void)
{
int i;
char *pBlock[3];
for(i = 0; i < 3; i++)
{
pBlock[i] = (char*)getMem(4096);
if(pBlock[i] == NULL){
printf("Error: The request of Block[%d] failed!\n", i);
return false;
}
}
showMem();
for(i = 3; i >= 0; i--)
{
retMem(pBlock[i]);
}
showMem();
return true;
}
int test3(void)
{
char *pBlock;
pBlock = (char*)getMem(5000);
if(pBlock == NULL)
{
printf("Error: The request of Block 5000 failed!\n");
return true;
}
return false;
}
int test4(void)
{
int i;
int j = 0;
char *pBlock[263];
for(i = 0; i < 100; i++)
{
pBlock[j] = (char*)getMem(32);
if(pBlock[j] == NULL)
{
printf("Error: The request of Block32[%d] failed!\n", i);
return false;
}
j++;
}
for(i = 0; i < 100; i++)
{
pBlock[j] = (char*)getMem(64);
if(pBlock[j] == NULL)
{
printf("Error: The request of Block64[%d] failed!\n", i);
return false;
}
j++;
}
for(i = 0; i < 50; i++)
{
pBlock[j] = (char*)getMem(256);
if(pBlock[j] == NULL)
{
printf("Error: The request of Block256[%d] failed!\n", i);
return false;
}
j++;
}
for(i = 0; i < 10; i++)
{
pBlock[j] = (char*)getMem(1024);
if(pBlock[j] == NULL)
{
printf("Error: The request of Block1024[%d] failed!\n", i);
return false;
}
j++;
}
for(i = 0; i < 3; i++)
{
pBlock[j] = (char*)getMem(4096);
if(pBlock[j] == NULL)
{
printf("Error: The request of Block4096[%d] failed!\n", i);
return false;
}
j++;
}
showMem();
for(j = 262; j >= 0; j--)
{
retMem(pBlock[j]);
}
showMem();
return true;
}
int test5(void)
{
char *pBlock;
pBlock = (char*)getMem(32);
if(pBlock == NULL){
printf("Error: The request of Block32 failed!\n");
return false;
}
retMem(pBlock);
retMem(pBlock);
showMem();
return true;
}
int main()
{
if(!initMem())
{
printf("Error: Memory Pool Initialization Failed!\n");
return false;
}
//test1();
//test2();
//test3();
//test4();
//test5();
freeMem();
return 0;
}
objects = main.o memory_pool.o
main : $(objects)
cc -o main $(objects)
.PHONY : clean
clean :
-rm main $(objects)