基于结构体数组实现静态内存池管理

注:这篇博客主要讲了我用C语言实现静态内存池管理的算法和思想。首先建立这些内存块的结构体索引。

然后用malloc申请我们需要管理的内存块。在申请好的内存池里,进行内存使用。申请用户需要的内存,

用的是轮询的方式,根据内存块的大小在几种不同的内存块中依次查找剩余空间。释放内存就是改变每块

内存的free size。在程序结束后,free全部的内存,销毁内存池。功能实现的手段比较原始,后期可以进行

改进。欢迎大家参考和指导。


静态内存池管理要求:

32字节的内存块数量100块

64字节的内存块数量100块
256字节的内存块数量50块
1024字节的内存块数量10块
4096字节的内存块数量3块

实现要求(给出函数原型,请大家实现函数体):
内存池初始化函数:int initMem(void),返回0成功,其他值失败
内存块申请函数:void *getMem(unsigned int size),成功返回内存块地址,失败返回NULL
内存块释放函数:int retMem(void *buf),返回0成功,其他值失败
内存池统计函数:void showMem(void),各内存当前申请数、释放数、成功失败情况统计,用printf输出显示即可

验证用测试用例(最低要求):
1、把32字节的内存块全部申请完->接着归还一块->再申请一块->全部释放完。要求showMem显示结果正确!
2、4096字节内存块全部申请再全部释放
3、5000字节内存块申请

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 <stdlib.h>
#include <stdio.h>
#include <malloc.h>
#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 < MemChunk32.num; 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 < MemChunk64.num; 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 < MemChunk256.num; 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 < MemChunk1024.num; 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 < MemChunk4096.num; 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 < MemChunk4096.num; 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 < MemChunk1024.num; 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 < MemChunk256.num; 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 < MemChunk64.num; 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 < MemChunk32.num; 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 < MemChunk4096.num; 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 < MemChunk1024.num; 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 < MemChunk256.num; 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 < MemChunk64.num; 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 < MemChunk32.num; 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 < MemChunk32.num; 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 < MemChunk64.num; 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 < MemChunk256.num; 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 < MemChunk1024.num; 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 < MemChunk4096.num; 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 < MemChunk32.num; i++)

{

free(pMemBlock32[i].addr);

}

for(i = 0; i < MemChunk64.num; i++)

{

free(pMemBlock64[i].addr);

}

for(i = 0; i < MemChunk256.num; i++)

{

free(pMemBlock256[i].addr);

}

for(i = 0; i < MemChunk1024.num; i++)

{

free(pMemBlock1024[i].addr);

}

for(i = 0; i < MemChunk4096.num; i++)

{

free(pMemBlock4096[i].addr);

}

printf("Memory Freed Successfully!\n");

return 0;

}


main.c


#include <stdio.h>
#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)









下载时请看下面说明,对写一个动态的内存池很有帮助。 这是一个用C++语言链表的方法实现的一个静态内存池代源码。原理就是先向系统申请一块大内存,然后把这一大块分隔成相等的很多小块,然后在这这些小块的首地址部份放一个结构体结构体中有一个值是用来标明这一小块是否使用中。在这里存放你要放存的数据就是用结构体首地址加结构体自身长度就得到要放数据的首地址了.具体看代码的实现吧。我说一下动态内存池的写法。那是我给公司写的就不能上传了。结构体静态内存池的这个差不多一样,只是增加了一个成员用来记录每一节点到大块内存的首地址在到本节点的一个尺寸长度值,做法也是先申请一块大内存。我先从释放说起吧,释放本节点时看自己的相邻节点是不是有释放掉的,如果有则合并掉他们成为一个块,如果碰到相邻的节点是另外的一个大块的话就不用合并了,原因他和自己所在的这一个大块内存上物理地址不是连续,这里一定要记住,释放过程算法怎么去写就看你的了。下面是分配写法要考虑的。在分配一小块内存给高层使用时,如果是分配在尾节点去分配的情况,那好办啊,尾节点如果不够分配了就直接从系统去申请一块大内存,节点连起来在分配,这里有可能会浪费掉一小块以结构体大小的一块内存,如果够分配就直接分配了。如果是在中间节点去分配,这里就要将释放时合并的如果大于现在要分配的就拆开来用,如果拆开剩余的那一部份只有结构体大小就不用在拆开了。这些都是要考虑的东西,优化加快速度就看你自己了.可能看时不些不明白,看静态内存的写法后你就明白了.有时我也要下载其他人共享的东西,所以就一分吧.哈哈~~~~
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

AllenSun-1990

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值