欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 运维知识 > linux >内容正文

linux

(转载)简单linux C++内存池

发布时间:2025/4/16 linux 34 豆豆
生活随笔 收集整理的这篇文章主要介绍了 (转载)简单linux C++内存池 小编觉得挺不错的,现在分享给大家,帮大家做个参考.
C++代码 ?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 在学习内存池的过程中可谓云游太虚。一般都是针对标准内存池再次实现。大部分以链表的形式讨论。诚然最正宗也最准确,但是相对比较晦涩,本文是针对刚刚接触内存池的同学写的。大大减少了对内存池整体认识的难度。    内存池: 如果程序中涉及频繁申请释放内存,并且每次使用的内存并不是很大,这时候应该考虑内存池。 内存池可以有有效的避免内存碎片的产生。 内存池的框架: class MemPool{ public: MemPool(){初始化分配N个小的内存块} ~MemPool(){真正删除整个分配了的内存空间} void* getmem(){获取内存(块)} void freemem(){释放内存到内存池中,这里并不是真正的释放掉内存,只是回收再利用;} private: struct LinkBlock * 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>    using namespace std;      /*      在内存池中分配固定大小的内存块       目的是加速内存分配速度,并且减少因重复分配相同   */      class CMemPool   {   public:              //创建大小为blockSize的内存块,内存池数目为预分配的数目preAlloc        CMemPool(int blockSize, int preAlloc = 0, int maxAlloc = 0);              ~CMemPool();              //获取一个内存块。如果内存池中没有足够的内存块,则会自动分配新的内存块        //如果分配的内存块数目达到了最大值,则会返回一个异常        void* Get();              //释放当前内存块,将其插入内存池        void Release(void* ptr);              //返回内存块大小        int BlockSize() const;              //返回内存池中内存块数目        int Allocated() const;              //返回内存池中可用的内存块数目        int Available() const;          private:       CMemPool();       CMemPool(const CMemPool&);       CMemPool& operator = (const CMemPool&);              enum       {           BLOCK_RESERVE = 128       };              typedef std::vector<char*> BlockVec;              int m_blockSize;       int         m_maxAlloc;       int         m_allocated;       BlockVec    m_blocks;   };      inline int CMemPool::BlockSize() const   {       return m_blockSize;   }      inline int CMemPool::Allocated() const   {       return m_allocated;   }      inline int CMemPool::Available() const   {       return (int) m_blocks.size();   }   #endif      ========================================================= MemPool.cpp       #include "MemPool.h"    CMemPool::CMemPool(int blockSize, int preAlloc, int maxAlloc):   m_blockSize(blockSize),   m_maxAlloc(maxAlloc),   m_allocated(preAlloc)   {       if ( preAlloc < 0 || maxAlloc == 0 || maxAlloc < preAlloc )       {           cout<<"CMemPool::CMemPool parameter error."<<endl;       }              int r = BLOCK_RESERVE;       if (preAlloc > r)           r = preAlloc;       if (maxAlloc > 0 && maxAlloc < r)           r = maxAlloc;       m_blocks.reserve(r);       for (int i = 0; i < preAlloc; ++i)       {           m_blocks.push_back(new char[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;               return new char[m_blockSize];           }           else           {               cout<<"CMemPool::get CMemPool exhausted."<<endl;               return (void *)NULL;           }       }       else       {           char* ptr = m_blocks.back();           m_blocks.pop_back();           return ptr;       }   }         void CMemPool::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> int main(int argc, char* argv[]) { CMemPool *m_cache =new CMemPool(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; delete m_cache;     return 0; }    完毕!    当然这只是探究内存池而已,更高级的比如线程安全,内存扩容,模板等等,仍需解决。 但是相信想初窥内存池门径应该还是有帮助的!
描述:以STL-vector为数据存储单元,实现简单的内存池功能。

总结

以上是生活随笔为你收集整理的(转载)简单linux C++内存池的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。