简单linux C++内存池

本文介绍了一种简单的内存池设计与实现方法,旨在减少内存碎片并提高内存分配效率。通过使用STL vector管理内存块,文章详细展示了内存池类的设计原理及其实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

http://my.youkuaiyun.com/cyebo/code/detail/37135
在学习内存池的过程中可谓云游太虚。一般都是针对标准内存池再次实现。大部分以链表的形式讨论。诚然最正宗也最准确,但是相对比较晦涩,本文是针对刚刚接触内存池的同学写的。大大减少了对内存池整体认识的难度。
 
内存池:
如果程序中涉及频繁申请释放内存,并且每次使用的内存并不是很大,这时候应该考虑内存池。
内存池可以有有效的避免内存碎片的产生。
内存池的框架:
classMemPool{
public:
MemPool(){初始化分配N个小的内存块}
~MemPool(){真正删除整个分配了的内存空间}
void* getmem(){获取内存(块)}
voidfreemem(){释放内存到内存池中,这里并不是真正的释放掉内存,只是回收再利用;}
private:
structLinkBlock * p;//把很多小内存块关联起来的结构,大部分写成链表的形式
mem_block* m_block;//一个小的内存块。
};
工作机制:
事先分配出一大块内存,再把这一大块分成很多小块。当程序中需要申请内存时就拿出一小块来用。用完了就把这一小块放回大块中(注意:这个小块内存并没释放掉!),只要不是一下用掉了所有一大块内存,无论多少次申请内存都是重复利用这些小的内存块。知道程序结束真正释放掉整片内存。
所以用内存池可以把大量的内存申请控制在可计算的范围内。内存碎片少。比如:如果用系统的new或者malloc申请10000次内存,可能要10000的小的内存空间,但是使用内存池只需申请100块空间,循环利用100次而已。作用显而易见!
 
为了让程序简单明了使用STL标准库的vector来充当小内存块的管理器。
vector<char*> vec; 这样每次申请的是vec的一个迭代器的空间。
 
代码非原创,稍稍做了改动而已。
========================================================================
MemPool.h
 
#ifndef _MEM_POOL_H  
#define _MEM_POOL_H   
#include <vector>  
#include <iostream>  
usingnamespace std; 
 
/*
    在内存池中分配固定大小的内存块 
    目的是加速内存分配速度,并且减少因重复分配相同 
*/ 
 
classCMemPool 
public
     
    //创建大小为blockSize的内存块,内存池数目为预分配的数目preAlloc  
    CMemPool(intblockSize, intpreAlloc = 0, intmaxAlloc = 0); 
     
    ~CMemPool(); 
     
    //获取一个内存块。如果内存池中没有足够的内存块,则会自动分配新的内存块  
    //如果分配的内存块数目达到了最大值,则会返回一个异常  
    void* Get(); 
     
    //释放当前内存块,将其插入内存池  
    voidRelease(void* ptr); 
     
    //返回内存块大小  
    intBlockSize() const
     
    //返回内存池中内存块数目  
    intAllocated() const
     
    //返回内存池中可用的内存块数目  
    intAvailable() const
     
private
    CMemPool(); 
    CMemPool(constCMemPool&); 
    CMemPool& operator = (constCMemPool&); 
     
    enum 
    
        BLOCK_RESERVE = 128 
    }; 
     
    typedefstd::vector<char*> BlockVec; 
     
    intm_blockSize; 
    int        m_maxAlloc; 
    int        m_allocated; 
    BlockVec    m_blocks; 
}; 
 
inlineint CMemPool::BlockSize() const 
    returnm_blockSize; 
 
inlineint CMemPool::Allocated() const 
    returnm_allocated; 
 
inlineint CMemPool::Available() const 
    return(int) m_blocks.size(); 
#endif 
 
=========================================================
MemPool.cpp
 
 
#include "MemPool.h"  
CMemPool::CMemPool(intblockSize, intpreAlloc, intmaxAlloc): 
m_blockSize(blockSize), 
m_maxAlloc(maxAlloc), 
m_allocated(preAlloc) 
    if( preAlloc < 0 || maxAlloc == 0 || maxAlloc < preAlloc ) 
    
        cout<<"CMemPool::CMemPool parameter error."<<endl; 
    
     
    intr = BLOCK_RESERVE; 
    if(preAlloc > r) 
        r = preAlloc; 
    if(maxAlloc > 0 && maxAlloc < r) 
        r = maxAlloc; 
    m_blocks.reserve(r); 
    for(inti = 0; i < preAlloc; ++i) 
    
        m_blocks.push_back(newchar[m_blockSize]); 
    
}    
CMemPool::~CMemPool() 
    for(BlockVec::iterator it = m_blocks.begin(); it != m_blocks.end(); ++it) 
    
        delete[] *it; 
    
 
void* CMemPool::Get() 
{   
     
    if(m_blocks.empty()) 
    
        if(m_maxAlloc == 0 || m_allocated < m_maxAlloc) 
        
            ++m_allocated; 
            returnnew char[m_blockSize]; 
        
        else 
        
            cout<<"CMemPool::get CMemPool exhausted."<<endl; 
            return(void*)NULL; 
        
    
    else 
    
        char* ptr = m_blocks.back(); 
        m_blocks.pop_back(); 
        returnptr; 
    
 
 
voidCMemPool::Release(void* ptr) 
{  
    memset(ptr,0,sizeof(char)*m_blockSize);//内存回收回来以后并没销毁,原数据仍在,所以应该清空
    m_blocks.push_back(reinterpret_cast<char*>(ptr)); 
}  
 
=========
main.h
 
#include "stdafx.h"
#include "MemPool.h"
#include <string.h>
intmain(intargc, char* argv[])
{
CMemPool *m_cache =newCMemPool(50,0,10);
 
char* src_date="abcdefg";
char*p1=(char*)(m_cache->Get());
char*p2=(char*)(m_cache->Get());
int*p3=(int*)(m_cache->Get());
strcpy(p1,src_date);
strcpy(p2,src_date);
p3[0]=9;p3[1]=25;
 
m_cache->Release(p1);
m_cache->Release(p2);
m_cache->Release(p3);
 
//把MemPool.cpp中void CMemPool::Release(void* ptr) 的
//memset(ptr,0,sizeof(char)*m_blockSize);注释掉可以验证每次内存回收以后是重复利用而非销毁
cout<<*(int*)(m_cache->Get())<<endl;
cout<<(char*)(m_cache->Get())<<endl;
cout<<(char*)(m_cache->Get())<<endl;
deletem_cache;
    return0;
}
 
完毕!
 
当然这只是探究内存池而已,更高级的比如线程安全,内存扩容,模板等等,仍需解决。
但是相信想初窥内存池门径应该还是有帮助的!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值