IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> C++知识库 -> 内存管理——小型对象分配器实践输出 -> 正文阅读

[C++知识库]内存管理——小型对象分配器实践输出

【注】此实践的基本思路来自《Modern C++ Design》

四层结构

在这里插入图片描述
在这里插入图片描述

实现Chunk

struct Chunk
{
	Chunk() : pData(nullptr), firstAvailableBlock_(0), blocksAvailable_(0)
	{
	}
	
	Chunk(size_t blockSize, unsigned char blocks)
	{
		pData = new unsigned char[blockSize * blocks];
		firstAvailableBlock_ = 0;
		blocksAvailable_ = blocks;
		unsigned char* p = pData_;
		// 给每个block编号
		for (unsigned char i = 0; i != blocks; p = p + blockSize)
		{
			*p = ++i;
		}
	}
	
	~Chunk()
	{
		if (pData)
		{
			delete[] pData;
			pData = nullptr;
		}
		
		firstAvailable_ = 0;
		blocksAvailable_ = 0;
	}
	
	Chunk(Chunk&& chunk)
	{
		pData = chunk.pData;
		chunk.pData = nullptr;
		firstAvailable_ = chunk.firstAvailable_;
		blocksAvailable_ = chunk.blocksAvailable_;
	}
	
	Chunk(Chunk& chunk)
	{
		pData = chunk.pData;
		chunk.pData = nullptr;
		firstAvailable_ = chunk.firstAvailable_;
		chunk.firstAvailable_ = 0;
		blocksAvailable_ = chunk.blocksAvailable_;
		chunk.blocksAvailable_ = 0;
	}
	
	Chunk& operator=(Chunk& chunk)
	{
		if (this != &chunk)
		{
			pData = chunk.pData;
			chunk.pData = nullptr;
			firstAvailable_ = chunk.firstAvailable_;
			chunk.firstAvailable_ = 0;
			blocksAvailable_ = chunk.blocksAvailable_;
			chunk.blocksAvailable_ = 0;
		}
		return *this;
	}
	
	Chunk& operator=(Chunk&& chunk)
	{
		pData = chunk.pData;
		chunk.pData = nullptr;
		firstAvailable_ = chunk.firstAvailable_;
		chunk.firstAvailable_ = 0;
		blocksAvailable_ = chunk.blocksAvailable_;
		chunk.blocksAvailable_ = 0;
		return *this;
	}
	
	void* allocate(size_t blocksize)
	{
		if (not blocksAvailable_) return nullptr;
		auto* pResult = pData + firstAvailableBlock_*blockSize;
		firstAvailableBlock_ = *pResult; // 获得下一块内存的索引
		--blocksAvailable_;
		return pResult;
	}
	
	void deallocate(void* p, size_t blockSize)
	{
		assert(p >= pData);
		auto* toRelease = static_cast<unsigned char*>(p);
		// 对齐校验
		assert((toRelease - pData) % blockSize == 0);
		*toRelease = firstAvailableBlock_;
		firstAvailableBlock_ = static_cast<unsigned char>((toRelease - pData) / blockSize);
		// 截断检查
		assert(firstAvailableBlock_ == (toRelease - pData) / blockSize);
		++blockAvailable_;
	}
	
	bool empty() const
	{
		return blocksAvailable_ == 0;
	}
	
	bool available() const
	{
		return not empty();
	}
	
	bool full() const
	{
		return firstAvailableBlock_ == 0 and blocksAvailable_ != 0;
	}
	
	bool used() const
	{
		return firstAvailableBlock_ != 0;
	}
	
	bool contains(void* p, size_t blockSize, unsigned char numBlocks) const
	{
		auto cp = static_cast<unsigned char*>(p);
		return pData <= p && p < pData + blockSize*numBlocks;
	}
	
private:	
	unsigned char* pData_;
	unsigned char firstAvailableBlock_;
	unsigned char blocksAvailable_;
};

初始化

在这里插入图片描述

执行完第一次分配

在这里插入图片描述

实现FixedAllocator

struct FixedAllocator
{
	FixedAllocator(size_t blockSize, unsigned char numBlocks) : blockSize_(blockSize), numBlocks_(numBlocks), chunks_({Chunk(blockSize_, numBlocks)}) allocChunk_(nullptr),deallocChunk_(nullptr)
	{
	}
	
	~FixedAllocator()
	{
		blockSize_ = 0;
		numBlocks_ = 0;
		chunks_.clear();
		allocChunk_ = nullptr;
		deallocChunk_ = nullptr;
	}
	
	void* allocate()
	{
		if (allocChunk_ == nullptr or allocChunk->empty())
		{
			auto it = std::find_if(chunks_.begin(), chunks_.end(), [](const Chunk& chunk){
				return	chunk.available();	
			});
			if (it != chunks_.end())
			{
				allocChunk_ = &(*it);
			}
			else
			{
				chunks_.emplace_back(Chunk(blockSize_, numBlocks_));
				allocChunk_ = &(chunks_.back());
				deallocChunk_ = &(chunks_.front());
			}
		}
		
		assert(allocChunk_ != nullptr);
		assert(allocChunk_->available());
		return allocChunk_.allocate(blockSize_);
	}
	
	void deallocate(void* p)
	{
		if (deallocChunk_)
		{
			if (deallocChunk_->contains(p, blockSize_, numBlocks_))
			{
				deallocChunk_->deallocate(p, blockSize_);
			}
			else
			{
				auto it = Chunks::iterator(deallocChunk_);
				while (++it != chunks_.end())
				{
					if (it->contains(p))
					{
						it->deallocate(p, blockSize_);
						deallocChunk_ = &(*it);
						return ;
					}
				}
				
				it = Chunks::iterator(deallocChunk_);
				assert(it != chunks_.begin());
				while(--it != chunks_.rend())
				{
					if (it->contains(p, blockSize_, numBlocks_))
					{
						it->deallocate(p, blockSize_);
						deallocChunk_ = &(*it);
						return ;
					}
				}
			}
		}
		else
		{
			auto it = std::find_if(chunks_.begin(), chunks_.end(), [this](const Chunk& chunk) {
				return chunk.used() and chunk.contains(p, blockSize_, numBlocks_);
			});
			if (it != chunks_.end())
			{
				deallocChunk_ = &(*it);
				deallocChunk_->deallocate(p, blockSize_);
			}
			else
			{
				assert(false);
			}
		}
	}
	
	size_t getBlockSize() const
	{
		return blockSize_;
	}
	
private:
	size_t blockSize_;
	unsigned char numBlocks_;
	using Chunks = std::vector<Chunk>;
	Chunks chunks_;
	Chunk* allocChunk_;
	Chunk* deallocChunk_;
};

实现SmallObjAllocator

struct SmallObjAllocator
{
	SmallObjAllocator(size_t chunkSize, size_t maxObjSize) 
					: chunkSize_(chunkSize), maxObjSize_(maxObjSize)
					, pool_(), pLastAlloc_(nullptr), pLastDealloc_(nullptr)
	{
		
	}
	
	void* allocate(size_t numBytes)
	{
		if (numBytes > maxObjSize_)
			return ::operator new(numBytes);
		else
		{
			if (pLastAlloc_ and pLastAlloc_->getBlockSize() == numBytes)
			{
				return pLastAlloc_->allocate();
			}
			
			// 此处可以二分查找优化
			auto it = std::find_if(pool_.begin(), pool_.end(), [numBytes](const FixedAllocator& alloc){
				return alloc.getBlockSize() == numBytes;
			});
			
			if (it != pool_.end())
			{
				return it->allocate();
			}
			esle
			{
				pool_.emplace_back(FixedAllocator(numBytes, chunkSize_ ));
				pLastAlloc_ = &(pool_.back());
				return pLastAlloc_->allocate();
			}
		}
	}
	
	void deallocate(void* p, size_t size)
	{
		if (size > maxObjSize_)
		{
			::operator delete(p);
		}
		else
		{
			if (pLastDealloc_ and pLastDealloc_->getBlockSize() == size)
			{
				pLastDealloc_->deallocate(p);
			}
			else
			{
				auto it = std::find_if(pool_.begin(), pool_.end(), [size](const FixedAllocator& alloc){
				return alloc.getBlockSize() == size;
			});
				
				assert(it != pool_.end());
				it->deallocate(p);
			}
		}
	}
	
private:
	size_t chunkSize_;
	size_t maxObjSize_;
	std::vector<FixedAllocator> pool_;
	FixedAllocator* pLastAlloc_;
	FixedAllocator* pLastDealloc_;
};

实现SmallObject

SmallObjAllocator& getSmallObjAlloc()
{
	static SmallObjAllocator alloc(5, 1024);
	return alloc;
}
struct SmallObject
{
	static void* operator new(size_t size)
	{
		return getSmallObjAlloc().allocate(size);
	}
	
	static void operator delete(void* p, size_t size)
	{
		getSmallObjAlloc().deallocate(p, size);
	}
	
	virtual ~Smal1Object(){}
};
  C++知识库 最新文章
【C++】友元、嵌套类、异常、RTTI、类型转换
通讯录的思路与实现(C语言)
C++PrimerPlus 第七章 函数-C++的编程模块(
Problem C: 算法9-9~9-12:平衡二叉树的基本
MSVC C++ UTF-8编程
C++进阶 多态原理
简单string类c++实现
我的年度总结
【C语言】以深厚地基筑伟岸高楼-基础篇(六
c语言常见错误合集
上一篇文章      下一篇文章      查看所有文章
加:2022-04-14 23:31:36  更:2022-04-14 23:34:35 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 0:18:18-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码