首页 > 代码库 > 简单的内存分配器

简单的内存分配器

采用自定义的operator运算符实现自己的内存分配策略,在某些时候可以提高程序的效率。

 

C++中的new运算符,具体工作流程如下:

1.调用operator new申请原始内存

2.调用place new表达式,执行类的构造函数

3.返回内存地址

而delete操作符的工作是:

1.调用对象的析构函数

2.调用operator delete释放内存

这里提供一个简单的内存分配器基类,凡是继承该类的class均具有自定义的operator new 和 operator delete

此示例来自《C++Primer》第四版

大概思想是用static变量维持一个链表,管理空闲的内存块。

代码如下:

 1 #ifndef NEW_H 2 #define NEW_H  3 #include <iostream> 4 #include <stdexcept> 5 #include <memory> 6  7 template <typename T> 8 class New 9 {10 public:11     void *operator new(std::size_t );12     void operator delete(void *, std::size_t );13     virtual ~New() { }14 protected:15     T *_next;16 private:17     static void addToFreeList(T *);     //将内存块加入链表18     static std::allocator<T> _alloc;     //内存分配器19     static T *_freeList;                //空闲内存的链表20     static const std::size_t _chunk;    //一次分配的块数21 };22 23 template <typename T> std::allocator<T> New<T>::_alloc;24 template <typename T> T *New<T>::_freeList = NULL;25 template <typename T> const std::size_t New<T>::_chunk = 24;26 27 28 template <typename T>29 void *New<T>::operator new(std::size_t sz)30 {31     if(sz != sizeof(T))32         throw std::runtime_error("wrong size");33     std::cout << "operator new" << std::endl;34 35     if(_freeList == NULL)36     {37         T *newList = _alloc.allocate(_chunk);38         for(size_t i = 0; i != _chunk; ++ i)39             addToFreeList(&newList[i]);40     }41 42     T *p = _freeList;43     _freeList = _freeList->New<T>::_next;44     return p;45 }46 47 template <typename T>48 void New<T>::operator delete(void *p, size_t sz)49 {50     std::cout << "operator delete" << std::endl;51     if(p != NULL)52         addToFreeList(static_cast<T *>(p));53 }54 55 56 template <typename T>57 void New<T>::addToFreeList(T *p)58 {59     p->New<T>::_next = _freeList;60     _freeList = p;61 }62 #endif  /*NEW_H*/

每次执行new时,调用我们自定义的operator new去空闲链表中取出一块内存,如果链表为空,则执行真正的申请内存操作。

每次delete时,把内存归还给链表。

这样减少了每次new都去申请内存的开销。

测试代码如下:

 1 #include "new.hpp" 2 #include <iostream> 3 using namespace std; 4  5 //使用继承的策略去使用这个内存分配器 6 class Test : public New<Test> 7 { 8  9 };10 11 int main(int argc, char const *argv[])12 {13     14     //调用自定义的new分配内存15     Test *pt = new Test;16     delete pt;17 18     //调用默认的new和delete19     pt = ::new Test;20     ::delete pt;21 22     //不会调用自定义的new和delete23     pt = new Test[10];24     delete[] pt; 25 26 }

 

简单的内存分配器