博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
简单的内存分配器
阅读量:6077 次
发布时间:2019-06-20

本文共 2800 字,大约阅读时间需要 9 分钟。

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

 

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

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

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

3.返回内存地址

而delete操作符的工作是:

1.调用对象的析构函数

2.调用operator delete释放内存

例如:

#include 
using namespace std;class Test{public: Test() { cout << "Test" << endl; } ~Test() { cout << "~Test" << endl; }};int main(int argc, char const *argv[]){ //这里的pt指向的是原始内存 Test *pt = static_cast
(operator new[] (5 * sizeof(Test))); for(int ix = 0; ix != 5; ++ix) { new (pt+ix)Test(); //调用定位new运算式 执行构造函数 } for(int ix = 0; ix != 5; ++ix) { pt[ix].~Test(); //调用析构函数,但是并未释放内存 } operator delete[] (pt); //释放内存}

 

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

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

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

#ifndef CACHED_OBJECT_HPP#define CACHED_OBJECT_HPP#include 
#include
#include
//debugtemplate
class CachedObject{public: void *operator new(std::size_t); void operator delete(void *, std::size_t); virtual ~CachedObject() { }protected: T *next_;private: static void addToFreeList(T*); //将内存块加入链表 static std::allocator
alloc_;//内存分配器 static T *freeStore_; //空闲内存的链表 static const std::size_t chunk_;//一次分配的块数};template
std::allocator
CachedObject
::alloc_;template
T *CachedObject
::freeStore_ = NULL;template
const std::size_t CachedObject
::chunk_ = 24;template
void *CachedObject
::operator new(std::size_t sz){ if(sz != sizeof(T)) throw std::runtime_error("CachedObject: wrong size object in operator new"); std::cout << "operator new " << std::endl; //DEBUG //没有空闲内存 if(freeStore_ == NULL) { T *array = alloc_.allocate(chunk_); for(std::size_t ix = 0; ix != chunk_; ++ix) { addToFreeList(&array[ix]); } } //取出一块内存,从链表取出第一个元素 T *p = freeStore_; freeStore_ = freeStore_->CachedObject
::next_; return p;}template
void CachedObject
::operator delete(void *p, std::size_t){ std::cout << "operator delete " << std::endl; //DEBUG if(p != NULL) addToFreeList(static_cast
(p));}template
void CachedObject
::addToFreeList(T *p){ //使用头插法 p->CachedObject
::next_ = freeStore_; freeStore_ = p;}#endif /* CACHED_OBJECT_HPP */

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

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

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

测试代码如下:

#include "CachedObject.hpp"#include 
using namespace std;//使用继承的策略去使用这个内存分配器class Test : public CachedObject
{};int main(int argc, char const *argv[]){ //调用自定义的new分配内存 Test *pt = new Test; delete pt; //调用默认的new和delete pt = ::new Test; ::delete pt; //不会调用自定义的new和delete pt = new Test[10]; delete[] pt; }

转载于:https://www.cnblogs.com/inevermore/p/4003710.html

你可能感兴趣的文章
MySQL的btree索引和hash索引的区别
查看>>
开源 免费 java CMS - FreeCMS1.2-标签 mailPage
查看>>
sql server 通过sql server 协议进行登录的解析
查看>>
按下返回键,不直接退出而是弹出对话框
查看>>
拦截器__call,_callstatic
查看>>
自学编程的技术大牛是如何进谷歌的
查看>>
IE6 和 IE8下翻页功能的失效差异问题
查看>>
NoSQL&MongoDB
查看>>
[node] 用 node-webkit 开发桌面应用
查看>>
HashTable 与HashMap的区别
查看>>
TiDB 在摩拜单车在线数据业务的应用和实践
查看>>
我的友情链接
查看>>
多使用工具方法
查看>>
超微型微博系统(简单实现)
查看>>
FruityWifi 2.0 试用体会
查看>>
redux资料
查看>>
Elasticsearch上遇到的部分问题及处理
查看>>
PE,Dos工具箱,自动安装linux的U盘制作
查看>>
SpringMVC + Hibernate + Spring集成Log4j日志插件
查看>>
你后台的Activity被系统回收怎么办:onSaveInstanceState
查看>>