首页 > 代码库 > 简单的内存分配器
简单的内存分配器
采用自定义的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 }
简单的内存分配器
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。