一开始想到要写一个内存池是因为项目过程中,需要用到一个链表进行数据的管理,但是因为需要不停的对链表中的节点进行增加和删除,因此如果不停的malloc和free,给我的感觉是会不会太浪费内存和CPU了?所以我开始想如何才能解决这个麻烦。
我的问题:一个拥有最大长度(MAX_LEN)的链表,然后我会不断的遍历链表取数据,并删除节点;也会不断的向链表插入新的数据节点;当插入时发现链表长度>MAX_LEN,就删除最开始插入的那个数据节点。
乍一看,这个问题如果用不停的malloc、free,insertList,getListItem这种方式来做,还是蛮简单的,但如果我并不想如此频繁的申请、释放内存呢?据说会减少内存碎片,并提高程序的运行效率。
上代码:
memoryPool.h
#ifndef MYMEMORYPOOL_H
#define MYMEMOryPOOL_H
#define LIST_SIZE 32
template<typename T>
class memoryPool
{
public:
memoryPool(unsigned int count = LISE_SIZE);
~memoryPool();
void* allocBuff();
void freeBuff(void* p);
protected:
void allocFreeList(unsigned int count = LIST_SIZE);
private:
memoryPool<T>* freeBuffList;
};
#endif
memoryPool.hpp
#include "memoryPool.h"
template<typename T>
memoryPool<T>::memoryPool(unsigned int count){
allocFreeList(count);
}
template<typename T>
memoryPool<T>::~memoryPool(){
memoryPool<T>* pCur=NULL;
for(pCur = freeBuffList; pCur != NULL; pCur = freeBuffList){
freeBuffList = freeBuffList->freeBuffList;
delete [](char*)pCur;
}
}
template<typename T>
void* memoryPool<T>::allocBuff(){
if(NULL == freeBuffList){
allocFreeList();
}
memoryPool<T>* pHead = freeBuffList;
freeBuffList = freeBuffList->freeBuffList;
return pHead;
}
template<typename T>
void memoryPool<T>::freeBuff(void *p){
memoryPool<T>* pHead = static_cast<memoryPool<T>*>(p);
pHead->freeBuffList = freeBuffList;
freeBuffList = pHead;
}
template<typename T>
void memoryPool<T>::allocFreeList(unsigned int count){
unsigned int itemSize = sizeof(T) > sizeof(memoryPool<T>*) ? sizeof(T) : sizeof(memoryPool<T>*);
memoryPool<T>* pItem = static_cast<memoryPool<T>*>(static_cast<void*>(new char[itemSize]));
freeBuffList = pItem;
for(int i = 0; i < (count-1); ++i){
pItem->freeBuffList = static_cast<memoryPool<T>*>(static_cast<void*>(new char[itemSize]));
pItem = pItem->freeBuffList;
}
pItem->freeBuffList = NULL;
}
myList.h:
#ifndef MYLIST_H
#define MYLIST_H
#include <windows.h>
#include <iostream>
#include "memoryPool.hpp"
typedef struct xxx{
struct xxx* next;
int a;
int b;
int c;
}xxx;
class myLocker{}
public:
myLocker();
~myLocker();
void Lock();
vid Unlock();
protected:
CRITICAL_SECTION m_locker;
;
class xxxList{
public:
xxxList();
~xxxList();
int freexxxList();
int insertxxxList(int a, int b, int c);
int getxxxitem(int a, int b);
private:
xxx* listHeader;
xxx* listTail;
unsigned int listLen;
memoryPool<xxx> *mPool;
myLocker mLock;
};
#endif
myList.cpp:
#include "myList.h"
myLocker::myLocker(){
InitializeCriticalSection(&m_locker);
}
myLocker::~myLocker(){
DeleteCriticalSection(&m_locker);
}
void myLocker::Lock(){
EnterCriticalSection(&m_locker);
}
void myLocker::Unlock(){
LevelCriticalSetion(&m_locker);
}
xxxList::xxxList():listHeader(NULL),listTail(NULL),listLen(0){
mPool = new memoryPool<xxx>;
}
xxxList::~xxxList(){
xxx *ptemp;
mLock.Lock();
while(NULL != listHeader){
ptemp = listHeader;
listHeader = listHeader->next;
free(ptemp);
ptemp = NULL;
}
listHeader = NULL;
listTail = NULL;
mLock.Unlock();
delete(mPool);
}
int xxxList::freexxxList(){
mLock.Lock();
if(NULL == listHeader){
mLock.Unlock();
return 0;
}
xxx *ptemp;
while(NULL != listHeader){
ptemp = listHeader;
listHeader = listHeader->next;
mPool->freeBuff(ptemp);
ptemp = NULL;
}
listHeader = NULL;
listTail = NULL;
listLen = 0;
mLock.Unlock();
return 0;
}
int xxxList::insertxxxList(int a, int b, int c){
xxx *ptemp = NULL;
mLock.Lock();
if(LIST_SIZE == listLen){
ptemp = listHeader;
listHeader = listHeader->next;
listLen --;
}
else{
ptemp = (xxx*)mPool->allocBuff();
if(NULL == ptemp){
mLock.Unlock();
//日志
return -1;
}
}
ptemp->a = a;
ptemp->b = b;
ptemp->c = c;
ptemp->next = NULL;
if(NULL == listHeader){
listHeader = ptemp;
}
else{
listTail->next = ptemp;
}
listLen++;
listTail = ptemp;
mLock.Unlock();
return 0;
}
int xxxList::getxxxItem(int a, int b){
int ret = 0;
xxx *cur = NULL;
xxx *pre = NULL;
mLock.LOCK();
if(NULL == listHeader){
mLock.Unlock();
return 0;
}
cur = listHeader;
do{
if((cur->a == a) && (cur->b == b)){
ret = cur->c;
if(cur == listHeader){
listHeader = cur->next;
mPool->freeBuff(cur);
cur = NULL;
}
else if(cur == listTail){
listTail = pre;
mPool->freeBuff(cur);
cur = NULL;
}
else{
pre->next = cur->next;
mPool->freeBuff(cur);
cur = pre->next;
}
listLen --;
break;
}
pre = cur;
cur = cur->next;
}while((pre != listTail) && (NULL != cur));
mLock.Unlock();
return ret;
}