注:这篇博客主要讲了我用C语言实现静态内存池管理的算法和思想。首先建立这些内存块的结构体索引。
然后用malloc申请我们需要管理的内存块。在申请好的内存池里,进行内存使用。申请用户需要的内存,
用的是轮询的方式,根据内存块的大小在几种不同的内存块中依次查找剩余空间。释放内存就是改变每块
内存的free size。在程序结束后,free全部的内存,销毁内存池。功能实现的手段比较原始,后期可以进行
改进。欢迎大家参考和指导。
静态内存池管理要求:
32字节的内存块数量100块
64字节的内存块数量100块4、所有提供的内存(各种大小)全部申请完,再全部释放完
5、申请一块32字节,对该内存块释放两次
memory_pool.h
#ifndef __MEMORY_POLL_H__
#define __MEMORY_POLL_H__
//定义内存池
struct Mem_Pool {
struct Mem_Chunk *MemChunk32;
struct Mem_Chunk *MemChunk64;
struct Mem_Chunk *MemChunk256;
struct Mem_Chunk *MemChunk1024;
struct Mem_Chunk *MemChunk4096;
};
//定义内存块
struct Mem_Chunk {
int num;
int size;
struct p_Mem_Block *pMemBlock;
}MemChunk32, MemChunk64, MemChunk256, MemChunk1024, MemChunk4096;
struct p_Mem_Block {
char *addr;
int request_num;
int free_num;
int free_size;
}pMemBlock32[100], pMemBlock64[100], pMemBlock256[50], pMemBlock1024[10], pMemBlock4096[3];
extern int initMem(void);
extern void *getMem(unsigned int size);
extern int retMem(void *buf);
extern void showMem(void);
extern int freeMem(void);
#endif
memory_pool.c
#include
#include
#include
#include "memory_pool.h"
//初始化内存块的大小、数量
struct Mem_Chunk MemChunk32 = {100, 32, NULL};
struct Mem_Chunk MemChunk64 = {100, 64, NULL};
struct Mem_Chunk MemChunk256 = {50, 256, NULL};
struct Mem_Chunk MemChunk1024 = {10, 1024, NULL};
struct Mem_Chunk MemChunk4096 = {3, 4096, NULL};
struct Mem_Pool MemPool = {&MemChunk32, &MemChunk64, &MemChunk256, &MemChunk1024, &MemChunk4096};
//用malloc申请内存,并将地址赋给定义的内存块结构体变量
int initMem(void)
{
int i;
for(i = 0; i
{
pMemBlock32[i].addr = (char*)malloc(MemChunk32.size);
if(NULL == pMemBlock32[i].addr) return -1;
pMemBlock32[i].request_num = 0;
pMemBlock32[i].free_num = 0;
pMemBlock32[i].free_size = MemChunk32.size;
}
for(i = 0; i
{
pMemBlock64[i].addr = (char*)malloc(MemChunk64.size);
if(NULL == pMemBlock64[i].addr) return -1;
pMemBlock64[i].request_num = 0;
pMemBlock64[i].free_num = 0;
pMemBlock64[i].free_size = MemChunk64.size;
}
for(i = 0; i
{
pMemBlock256[i].addr = (char*)malloc(MemChunk256.size);
if(NULL == pMemBlock256[i].addr) return -1;
pMemBlock256[i].request_num = 0;
pMemBlock256[i].free_num = 0;
pMemBlock256[i].free_size = MemChunk256.size;
}
for(i = 0; i
{
pMemBlock1024[i].addr = (char*)malloc(MemChunk1024.size);
if(NULL == pMemBlock1024[i].addr) return -1;
pMemBlock1024[i].request_num = 0;
pMemBlock1024[i].free_num = 0;
pMemBlock1024[i].free_size = MemChunk1024.size;
}
for(i = 0; i
{
pMemBlock4096[i].addr = (char*)malloc(MemChunk4096.size);
if(NULL == pMemBlock4096[i].addr) return -1;
pMemBlock4096[i].request_num = 0;
pMemBlock4096[i].free_num = 0;
pMemBlock4096[i].free_size = MemChunk4096.size;
}
printf("Memory Initialize Successfully!\n");
return 0;
}
void *getMem(unsigned int size)
{
int i, free_size;
char *pBlock;
if(size > 4096) return NULL;
if(size > 1024)
{
for(i = 0; i
pBlock = (char *)pMemBlock4096[i].addr;
free_size = pMemBlock4096[i].free_size;
if(free_size >= size){
pBlock = pBlock + 4096 - free_size;
pMemBlock4096[i].free_size -=size;
pMemBlock4096[i].request_num++;
return pBlock;
}
}
return NULL;
}
if(size > 256)
{
for(i = 0; i
pBlock = (char *)pMemBlock1024[i].addr;
free_size = pMemBlock1024[i].free_size;
if(pMemBlock1024[i].free_size >= size){
pBlock = pBlock + 1024 - free_size;
pMemBlock1024[i].free_size -=size;
pMemBlock1024[i].request_num++;
return pBlock;
}
}
return NULL;
}
if(size > 64)
{
for(i = 0; i
pBlock = (char *)pMemBlock256[i].addr;
free_size = pMemBlock256[i].free_size;
if(pMemBlock256[i].free_size >= size){
pBlock = pBlock + 256 - free_size;
pMemBlock256[i].free_size -=size;
pMemBlock256[i].request_num++;
return pBlock;
}
}
return NULL;
}
if(size > 32)
{
for(i = 0; i
pBlock = (char *)pMemBlock64[i].addr;
free_size = pMemBlock64[i].free_size;
if(pMemBlock64[i].free_size >= size){
pBlock = pBlock + 64 - free_size;
pMemBlock64[i].free_size -=size;
pMemBlock64[i].request_num++;
return pBlock;
}
}
return NULL;
}
if(size > 0)
{
for(i = 0; i
pBlock = (char *)pMemBlock32[i].addr;
free_size = pMemBlock32[i].free_size;
if(pMemBlock32[i].free_size >= size){
pBlock = pBlock + 32 - free_size;
pMemBlock32[i].free_size -=size;
pMemBlock32[i].request_num++;
return pBlock;
}
}
return NULL;
}
return NULL;
}
int retMem(void *buf)
{
int i, size;
char *pBlock;
char *pBuf = buf;
for(i = 0; i
pBlock = pMemBlock4096[i].addr;
if(pBuf >= pBlock && pBuf <= pBlock + 4096){
pMemBlock4096[i].free_size = pBlock + 4096 - pBuf;
pMemBlock4096[i].free_num++;
return 0;
}
}
for(i = 0; i
pBlock = pMemBlock1024[i].addr;
if(pBuf >= pBlock && pBuf <= pBlock + 1024){
pMemBlock1024[i].free_size = pBlock + 1024 - pBuf;
pMemBlock1024[i].free_num++;
return 0;
}
}
for(i = 0; i
pBlock = pMemBlock256[i].addr;
if(pBuf >= pBlock && pBuf <= pBlock + 256){
pMemBlock256[i].free_size = pBlock + 256 - pBuf;
pMemBlock256[i].free_num++;
return 0;
}
}
for(i = 0; i
pBlock = pMemBlock64[i].addr;
if(pBuf >= pBlock && pBuf <= pBlock + 64){
pMemBlock64[i].free_size = pBlock + 64 - pBuf;
pMemBlock64[i].free_num++;
return 0;
}
}
for(i = 0; i
pBlock = pMemBlock32[i].addr;
if(pBuf >= pBlock && pBuf <= pBlock + 32){
pMemBlock32[i].free_size = pBlock + 32 - pBuf;
pMemBlock32[i].free_num++;
return 0;
}
}
return -1;
}
void showMem(void)
{
int i, request_number, free_number;
for(i = 0; i
{
request_number = pMemBlock32[i].request_num;
free_number = pMemBlock32[i].free_num;
printf("The Memory_Chunk_32 pMemBlock32[%d]\n", i);
printf("request_number: %d free_number: %d\n",request_number, free_number);
}
for(i = 0; i
{
request_number = pMemBlock64[i].request_num;
free_number = pMemBlock64[i].free_num;
printf("The Memory_Chunk_64 pMemBlock64[%d]\n", i);
printf("request_number: %d free_number: %d\n",request_number, free_number);
}
for(i = 0; i
{
request_number = pMemBlock256[i].request_num;
free_number = pMemBlock256[i].free_num;
printf("The Memory_Chunk_256 pMemBlock256[%d]\n", i);
printf("request_number: %d free_number: %d\n",request_number, free_number);
}
for(i = 0; i
{
request_number = pMemBlock1024[i].request_num;
free_number = pMemBlock1024[i].free_num;
printf("The Memory_Chunk_1024 pMemBlock1024[%d]\n", i);
printf("request_number: %d free_number: %d\n",request_number, free_number);
}
for(i = 0; i
{
request_number = pMemBlock4096[i].request_num;
free_number = pMemBlock4096[i].free_num;
printf("The Memory_Chunk_4096 pMemBlock4096[%d]\n", i);
printf("request_number: %d free_number: %d\n",request_number, free_number);
}
}
//销毁内存池,将申请的内存全部释放掉。
int freeMem(void)
{
int i;
for(i = 0; i
{
free(pMemBlock32[i].addr);
}
for(i = 0; i
{
free(pMemBlock64[i].addr);
}
for(i = 0; i
{
free(pMemBlock256[i].addr);
}
for(i = 0; i
{
free(pMemBlock1024[i].addr);
}
for(i = 0; i
{
free(pMemBlock4096[i].addr);
}
printf("Memory Freed Successfully!\n");
return 0;
}
main.c
#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 -1;
}
}
if(retMem(pBlock[99]) == 0)
{
printf("The 100th Block is freed.\n");
}
else {
printf("Error: The 100th Block can't be freed!\n");
return -1;
}
pBlock[99] = (char*)getMem(32);
if(pBlock[99] == NULL){
printf("Error: The request of Block[99] failed!\n");
return -1;
}
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 -1;
}
}
for(i = 3; i >= 0; i--)
{
retMem(pBlock[i]);
}
showMem();
return 0;
}
int test3(void)
{
char *pBlock;
pBlock = (char*)getMem(5000);
if(pBlock == NULL){
printf("Error: The request of Block 5000 failed!\n");
return 0;
}
return -1;
}
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 -1;
}
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 -1;
}
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 -1;
}
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 -1;
}
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 -1;
}
j++;
}
for(j = 262; j >= 0; j--)
{
retMem(pBlock[j]);
}
showMem();
return 0;
}
int test5(void)
{
char *pBlock;
pBlock = (char*)getMem(32);
if(pBlock == NULL){
printf("Error: The request of Block32 failed!\n");
return -1;
}
retMem(pBlock);
retMem(pBlock);
showMem();
return 0;
}
int main()
{
if(initMem() == -1)
{
printf("Error: Memory Pool Initialization Failed!\n");
return -1;
}
//test1();
//test2();
//test3();
//test4();
//test5();
freeMem();
return 0;
}
Makefile
objects = main.o memory_pool.o
main : $(objects)
cc -o main $(objects)
.PHONY : clean
clean :
-rm main $(objects)