[原创]:改进的相对完善的c内存池

 

/**
*作者:netpetboy Email:netpetboy@163.com
*本程序为内存池解决方案
*程序设计中兼顾了小内存碎片中等内寻管理以及大块内存
*设计中参阅了网络的部分内存池设计原理,取其精华,本程序池对象分为三个部分,(0-InitMemPool)*Align(4,8,16等等)大小
*范围内的内存申请在池链表的同时又一个池指针索引指向池,比如,设置InitMemPool为256,就会有256个被提前初始化,索引依次
*为1、2、3、...256,对应管理的内存片大小为1*Align、2*Align、3*Align.....256*Align,其中Align为基本对齐单位,默认为4,如果申
*请的内存比较大可以设置为8,前256(InitMemPool)个会索引指针,通过下标就能引用,大于此范围的内存在InitMemPool链表之后
*紧密附加在后面,不会产生空档,提起需要便利后面部分方能得到,当申请的内存大于255*255*Align的时候就超出了本内存池的管理范围
*一般来讲即使最小设置Align为4也可以达到260K的最大内存管理,如果不够用可以加大Align,再大了管理起来也就没意思了,内存管理的
*每块内存前面保留2个字符的unsigned short int类型的大小数据,用来保存数据块大小,方便free的时候使用
*本程序经过车是性能已经超过我所参考的大部分程序池,安全方面暂时没有加入线程锁,接下来的改进可能将锁保存在池链表中,对单项进行加锁
*/

memory.c


#include "memory.h"

static MemPool * heap=NULL;//分界线
static MemPool * top_of_heap=NULL;//池集合的头部
static MemPool * btm_of_heap=NULL;//池集合的尾部
int index=1;
MemPool * poolIndex[InitMemPool];
static long totalByte;
static Int AlignNum(Int size)
{
return (((size)+Align-1) &~ (Align-1));// 按Align对齐字节对齐
}
/**
*取会给定结构的池结构体
*/
MemPool * GetPool(unsigned int name)
{
   MemPool * p=poolIndex[InitMemPool-1];
   while(p->next!=heap->next)
   {
    if(p->name==name)
    {
     return p;
    }
    else
     p=p->next;
   }
return NULL;
}

/*新定义一个池项*/
MemPool *NewPoolItem(unsigned int name)
{
if(btm_of_heap!=NULL)
{
   if(name<InitMemPool)
    return poolIndex[Align-1];
   else
   {
    if(heap->next!=NULL)
    {
     MemPool *p;
     /*基本链表设置*/
     heap->name=name;
     heap->first=NULL;
     heap->last=NULL;
     heap->current=NULL;
     /*设置杂项*/
     heap->max_memory=0;
     heap->init_item=0;
     heap->per_expend_item=0;
     heap->current_item=0;
     heap->total_item=0;

     p=heap;
     heap=heap->next;
     return p;
    }
    else
    {
     ExpendPool();
     return NewPoolItem(name);
    }
   }
}
else
{
   InitPool();
   return NewPoolItem(name);
}
}
/*初始化池*/
void InitPool(void)
{
int blk;
MemPool *p;
heap=(MemPool *)malloc(sizeof(MemPool));/*创建第一个块*/
/*设置初始值*/
heap->name=1;/*设置第一个为1*Align的大小*/
heap->first=NULL;
heap->last=NULL;
heap->current=NULL;
    /*设置杂项*/
heap->max_memory=0;
heap->init_item=0;
heap->per_expend_item=0;
heap->current_item=0;
heap->total_item=0;

heap->max_memory=10;
btm_of_heap=heap;
poolIndex[0]=heap;/*把第一个装入数组的第一个,以便索引适用*/
p=heap;
for(blk=1;blk<InitMemPool;++blk)
{
   p->next=(MemPool *)malloc(sizeof(MemPool));
   p=p->next;
   /*设置初始值*/
   p->name=blk+1;
   p->first=NULL;
    p->last=NULL;
    p->current=NULL;
    /*设置杂项*/
    p->max_memory=0;
    p->init_item=0;
    p->per_expend_item=0;
    p->current_item=0;
    p->total_item=0;

   poolIndex[blk]=p;/*装入剩下的部分到索引表*/

}
p->next=NULL;
top_of_heap=p;
heap=p;/*标示移动到poolIndex的最后面,如果有超出Index大小的新池就用这个指针来分隔标示*/


}
void ExpendPool(void)
{
int blk;
MemPool *p;
heap->next=(MemPool *)malloc(sizeof(MemPool));/*创建第一个块*/
heap=heap->next;
p=heap;
for(blk=1;blk<ExpendMemPool;++blk)
{
   p->next=(MemPool *)malloc(sizeof(MemPool));
   p=p->next;
}
p->next=NULL;
top_of_heap=p;
}
void FreePool(MemPool *p)
{
if(p!=NULL)
{
   p->next=heap;
   heap=p;
}
return;
}


/*初始化项*/
void InitItem(unsigned int name)
{
int blk;
MemItem *ip;/*项的链表指针*/
/*构造容器*/
MemPool *p;//=GetPool(name);
if(btm_of_heap==NULL)
{
   p=NewPoolItem(name);
}
else if(name<=InitMemPool)
   p=poolIndex[name-1];
else
        p=GetPool(name);

p->total_item+=(p->init_item==0?InitMemItem:p->init_item);
p->first=(MemItem *)malloc(name*Align);/*创建第一个块*/

ip=p->first;
for(blk=1;blk<(p->init_item==0?InitMemItem:p->init_item);++blk)
{
   ip->next=(MemItem *)malloc(name*Align);
   ip=ip->next;
}
ip->next=NULL;
p->last=ip;
   totalByte+=name*Align*(p->init_item==0?InitMemItem:p->init_item);

}
/*扩展当前池项的下属内存块*/
void ExpendItem(unsigned int name)
{
int blk;
MemItem *ip;/*项的链表指针*/
/*构造容器*/

MemPool *p;

if(name<=InitMemPool)
   p=poolIndex[name-1];
else
        p=GetPool(name);


p->total_item+=(p->per_expend_item==0?ExpendMemItem:p->per_expend_item);
p->last->next=(MemItem *)malloc(name*Align);/*创建第一个块*/
index++;
ip=p->last->next;
for(blk=1;blk<(p->per_expend_item==0?ExpendMemItem:p->per_expend_item);++blk)
{
   ip->next=(MemItem *)malloc(name*Align);
   ip=ip->next;
   index++;
}
ip->next=NULL;
p->last=ip;
totalByte+=name*Align*(p->per_expend_item==0?ExpendMemItem:p->per_expend_item);
//printf("kuozan ");

}
/*申请心内存-〉内存池*/
void *New(unsigned int name)
{
//MemItem *ip;/*项的链表指针*/
/*构造容器*/
if(totalByte>MaxMemory)
   return NULL;/**申请的总内存过大,请调大默认最大内存设置或者检察内寻泄露*/
if(name>=Align*255*255)
{
   MemItem *ip=(MemItem *)malloc(name+2);
   ip->size=0;
   Short * size=(Short *)ip;
        ++size;/*移动short长度单位*/
       return size;/*此处返回的是向后偏移过的指针*/
}
name=(((name+2)+Align-1) &~ (Align-1))/Align;
MemPool *p;
if(btm_of_heap==NULL)
{
   p=NewPoolItem(name);
   InitItem(name);
}

if(name<=InitMemPool)
   p=poolIndex[name-1];
else
        p=GetPool(name);


if(p->first!=NULL)
{
   if(p->first->next!=NULL)
   {
    MemItem *ip;
    ip=p->first;
    p->first=p->first->next;
    p->current_item++;
    ip->size=name;
    Short * size=(Short *)ip;//转化为Short指针
    ++size;/*移动short长度单位*/

    return size;/*此处返回的是向后偏移过的指针*/
   }
   else
   {
    ExpendItem(name);
    return New(name*Align-2);
   }
}
else
{
   InitItem(name);
   return New(name*Align-2);
}
}
/*内存池回收*/
void Free(void *myp)
{
Short * size=(Short *)myp;//转化为Short指针
--size;/*向前移动short位移*/
MemItem *ip=(MemItem *)size;/*转化回来*/
MemPool *p;
if(ip->size==0)
{
   free(ip);
   return;
}
if(ip->size<=InitMemPool)
   p=poolIndex[ip->size-1];
else
        p=GetPool(ip->size);

if(p==NULL)
{
   printf("试图释放一个不属于池的指针,直接释放了");
   return;
}

if(p->first!=NULL)
{
   ip->next=NULL;
   p->last->next=ip;
   p->last=p->last->next;
   p->current_item--;
}
else
{
   printf("产生了一个野指针");
}
return;
}
/*输出调试函数*/
void PrintPool(void)
{
MemPool * pool=btm_of_heap;
while(pool->next!=NULL)
{
   printf("/n名称%i 共有%i 使用%i,初始化:%i 扩展%i 首地址%p 最后地址%p 当前地址%p 链表地 址:%p/n",pool->name,pool->total_item,pool->current_item,pool->init_item,pool->per_expend_item,pool->first,pool->last,pool->current,pool->next);
   if(pool->total_item>0)
   {
    MemItem * mi=pool->first;
    while(mi->next!=NULL)
    {
     printf("--/t%p",mi);
     mi=mi->next;
    }
   }
   pool=pool->next;
}
}

memory.h

#ifndef MemPool_H__
#define MemPool_H__
#define InitMemPool 10 //初始化池所能拥有的数量,不能超过255*255
#define ExpendMemPool 5 //每次扩展池多少项
#define Align 4       //对齐步进单位,4,8,16等等,每项所能容纳的最大内存为Align*index,index为short int,所以单项最大容量为Align*255*255字节,4字节对齐最大为260K,8字节对齐为512K
#define InitMemItem 100 //初始化池所能拥有的数量不能超过255*255
#define ExpendMemItem 100 //每次扩展池多少项。不能超过255*255
#define MaxMemory 1024*1024*300 //内存池最大容量 300M
#define new(type) ((type *)(New(sizeof(type))))
#define sizes sizeof(MemPool)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "types.h"

/**
*该结构用一个自增长的链表结构体保存分链表,每个结构体中包含具体链表的头部、尾部和空闲分界线指针,维护一个链表
*大致结构如下:
*            MemPool
*     V       V      V      ...
*   链表1   链表2   链表3   ...
*通过这样一个结构系统就可以灵活增加减少系统池,并且可以控制池内结构,控制总数据量
*
*/

typedef union _MemItem MemItem;
typedef struct _MemPool MemPool;

union _MemItem
{
MemItem *next;
Short size;
};

/*池集合*/
struct _MemPool
{
int name;//名称,同item_size,不管什么类型,申请的同一大小内存快放在同一个内存管理区域,视为同一名称,
long max_memory;//最多占用的内存
int init_item;//初始化多少item
int per_expend_item;//每次扩展时一次申请多少项
int current_item;//当前有多少项被使用
int total_item;//共有多少项
MemItem * first;//IO池头地址
MemItem * last;//IO池最后一项的地址
MemItem * current;//IO池分割空闲和使用中的分割地址
MemPool *next;//自身的链表结构
};


/**
*取会给定结构的池结构体
*/
static Int AlignNum(Int size);
MemPool * GetPool(unsigned int name);
MemPool *NewPoolItem(unsigned int name);
void InitPool(void);/*初始化池*/
void ExpendPool(void);/*扩展池*/
void FreePool(MemPool * p);/*释放池*/


void InitItem(unsigned int name);//初始化具体项的链表
void *New(unsigned int name);//初始化具体项的链表
void ExpendItem(unsigned int name);//初始化扩展项的链表
void Free(void *myp);//释放具体一项
void PrintPool(void);

#endif

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值