定制new和delete
来源:互联网 发布:mac突然无法连接wifi 编辑:程序博客网 时间:2024/05/22 22:34
在看《effective C++》第8章(定制new和delete)时,发现自己对new和delete理解的并不是那么深刻。
为什么要定制new和delete呢,因为在某些环境下(嵌入式),定制的new和delete效率会更高。
我在之前的文章“重载new和delete检测内存泄漏”中也做过类似的总结。
下面的例子中重载了class-specific new和class-specific delete
void* T::operator new ( std::size_t count );
void T::operator delete ( void* ptr );
如果想使用定制的new和delete需要继承fixedSizeResourcePool类。
总内存(使用了栈内存模拟)的大小固定,被平均分配成8个字节大小的内存块,每次new取其中一块,delete回收一块。
还是看代码吧。
为什么要定制new和delete呢,因为在某些环境下(嵌入式),定制的new和delete效率会更高。
我在之前的文章“重载new和delete检测内存泄漏”中也做过类似的总结。
下面的例子中重载了class-specific new和class-specific delete
void* T::operator new ( std::size_t count );
void T::operator delete ( void* ptr );
如果想使用定制的new和delete需要继承fixedSizeResourcePool类。
总内存(使用了栈内存模拟)的大小固定,被平均分配成8个字节大小的内存块,每次new取其中一块,delete回收一块。
还是看代码吧。
借用《effective C++》Item 50中的一句话:编写一个几乎能工作的自定义内存管理器相当容易,编写一个工作得很好的要困难得多。
#include <cstdio>using namespace std;typedef long unsigned int uint32_t;typedef unsigned char uint8_t;typedef unsigned char Alignment;typedef void* MemAddress;template<typename T, Alignment ALIGNMENT = 8>class fixedSizeResourcePool{public: //根据输入,初始化一块内存 //iNumOfObjects:内存块数量 //address:内存起始位置 //name_p:内存名字 static void init(const int iNumOfObjects, const MemAddress address, const char * name_p) {name_p_ = const_cast<char*>(name_p);uint8_t* currAddress = reinterpret_cast<uint8_t*>(address);for (int i = 0; i < iNumOfObjects; i++){ //做到8字节对齐,便于CPU快速寻址const uint8_t alignmentError = reinterpret_cast<uint32_t>(currAddress) %ALIGNMENT; if (alignmentError != 0){ //去除多余位置 currAddress += (ALIGNMENT - alignmentError);} //这里将内存分块:内存本身不变,poolInfo_.freeList_p_在变linkedList* tmp_p = reinterpret_cast<linkedList*>(currAddress);//point to currAddress addresstmp_p->next_p_ = poolInfo_.freeList_p_; //poolInfo_.freeList_p_->next_p_ = poolInfo_.freeList_p_;poolInfo_.freeList_p_ = tmp_p; printf("init:: poolInfo_.freeList_p_ = %x \n",poolInfo_.freeList_p_);//将内存块按sizeof(T)的大小分块currAddress += sizeof(T);}poolInfo_.numOfObjects_ = iNumOfObjects;printf("fixedSizeResourcePool %s initialized with iNumOfObjects: %d, sizeof(T): %d, totalBuffer: %d, Address: 0x%08x, ALIGNMENT: %d \n", name_p_, iNumOfObjects, sizeof(T), iNumOfObjects * sizeof(T), address, ALIGNMENT); } //重载operator new static void *operator new(uint32_t size) throw() { linkedList* tmp_p = poolInfo_.freeList_p_; if (tmp_p != 0) { printf("new:: poolInfo_.freeList_p_ = %x \n",poolInfo_.freeList_p_); printf("new:: poolInfo_.freeList_p_->next_p_ = %x \n",poolInfo_.freeList_p_->next_p_); //每次在链表中获取一块fixedSize的内存 poolInfo_.freeList_p_ = poolInfo_.freeList_p_->next_p_; poolInfo_.numAllocatedObjects_++; return tmp_p; } else { printf("no pool resource \n"); return 0; } } //placement new static void* operator new(uint32_t size, void *p) { return p; } //重载operator delete static void operator delete(void * p) { //每次在链表中删除一块fixedSize的内存 linkedList* tmp_p = reinterpret_cast<linkedList*> (p); tmp_p->next_p_ = poolInfo_.freeList_p_; poolInfo_.freeList_p_ = tmp_p; poolInfo_.numAllocatedObjects_--; } static inline int getNumFreeObjects() { return poolInfo_.numOfObjects_ - poolInfo_.numAllocatedObjects_; } class linkedList { private: linkedList* next_p_; friend class fixedSizeResourcePool; }; struct poolInfo { linkedList* freeList_p_; //链表 int numAllocatedObjects_; //已分配内存块 int numOfObjects_; //总内存块 }; private: static poolInfo poolInfo_; static char* name_p_;protected: fixedSizeResourcePool(void) {}; virtual ~fixedSizeResourcePool() {};}; template<typename T, Alignment ALIGNMENT>typename fixedSizeResourcePool<T, ALIGNMENT>::poolInfo fixedSizeResourcePool<T, ALIGNMENT>::poolInfo_ = {0, 0, 0}; template<typename T, Alignment ALIGNMENT>char* fixedSizeResourcePool<T, ALIGNMENT>::name_p_ = 0; class myClass: public fixedSizeResourcePool<myClass, 8>{ public: myClass():fixedSizeResourcePool<myClass>() { }};int main(){ const int num= 10; //phyMem is sizeof(myClass)*num = 80 byte //在栈内存的基础上分配内存 char phyMem[sizeof(myClass)*num]; myClass::init(num, phyMem, "phy_Mem" ); myClass *mO = new myClass; myClass *mO2 = new myClass; int n = fixedSizeResourcePool<myClass, 8>::getNumFreeObjects(); printf("After new, The memory left = %d \n", n); delete mO; delete mO2; n = fixedSizeResourcePool<myClass, 8>::getNumFreeObjects(); printf("After delete, The memory left = %d \n", n);}
0 0
- 定制new和delete
- 定制new和delete
- 8.定制new和delete
- [C++]定制new和delete
- Part8:定制new和delete
- Effective C++读书笔记---定制new和delete
- Effective C++(八)定制new和delete
- effective C++: 8.定制new和delete
- Effective C++ 8. 定制 new 和 delete
- Effective C++(八)定制new和delete
- 第八章 定制new和delete
- 《Effective C++》定制new和delete
- effective C++读书笔记八 —— 定制new 和delete
- Effective C++读书笔记 第八部分 定制new和delete
- Effective C++ --8 定制new和delete && 9杂谈讨论
- 定制new和delete更改内存管理方案
- Effective C++ 第八章(定制new和delete)
- Effective C++ 笔记 第八部分 定制new和delete
- Android如何保存文件到sd卡,及期间遇到的各种问题
- 错误
- IIS添加.net framework 4的支持
- tsar的使用
- Swap Nodes in Pairs 交换LinkList的相邻节点
- 定制new和delete
- Windows下的Mysql日志操作
- 无限轮播
- abas ERP – ERP行业中的“隐藏冠军”
- dos中mybatis generator自动生成出现xml parsers Error 前言中不允许有内容解决方法
- JavaScript跨域总结与解决办法
- VR/AR动手玩(一):在Android应用中集成opencv
- JS获取当前时间戳的方法
- BPMN2.0规范