码迷,mamicode.com
首页 > 其他好文 > 详细

简单的内存分配器

时间:2014-10-05 19:54:28      阅读:262      评论:0      收藏:0      [点我收藏+]

标签:style   blog   color   io   os   使用   ar   for   sp   

采用自定义的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和delete
19     pt = ::new Test;
20     ::delete pt;
21 
22     //不会调用自定义的new和delete
23     pt = new Test[10];
24     delete[] pt; 
25 
26 }

 

简单的内存分配器

标签:style   blog   color   io   os   使用   ar   for   sp   

原文地址:http://www.cnblogs.com/gjn135120/p/4007202.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!