zoukankan      html  css  js  c++  java
  • 简单的内存分配器

    采用自定义的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 }
  • 相关阅读:
    学习的原动力
    “六顶思考帽”给我的启示
    关于DataSet与Strongly typed DataSet几点思考(原创)
    设计模式之Singleton和Factory
    CentOS修改网络配置
    Proxmox VE(PVE)安装教程
    CentOS开启SELinux导致samba无法访问的解决办法
    nano编辑器使用教程
    CentOS 如何挂载硬盘
    PVE硬盘直通
  • 原文地址:https://www.cnblogs.com/gjn135120/p/4007202.html
Copyright © 2011-2022 走看看