重写allocate

allocate重写简要

  1. 一般STL库里的容器都会使用allocator来分配内存
  2. 实现自己的allocator可以达到让容器使用自身的内存管理
  3. 实现allocator不必重载allocator类,随便开一个新类即可
  4. allocator有五个必须有的函数
    • allocate: 用于开辟内存,功能类似operator new
    • deallocate: 回收内存,功能类似operator delete
    • construct: 调用构造函数
    • destroy: 调用释构函数
    • 重绑用的拷贝函数
template <typename T>
class SharedMemAlloc {
public:
	using value_type = T;

	typedef T* pointer;
	typedef const T* const_pointer;

	typedef T& reference;
	typedef const T& const_reference;

	using size_type = size_t;

	SharedMemAlloc(){
		std::cout << "do create SharedMemAlloc!!!" << std::endl;
	}

    // 重绑用的构造函数
	template <class _Other>
	constexpr SharedMemAlloc(const SharedMemAlloc<_Other>&) noexcept {}

	inline pointer allocate(size_type _Count, const void* _Hint = nullptr) {
		int total = _Count * sizeof(T) / sizeof(char);
		std::cout << "trying to SharedMemAlloc allocate:" << _Count << ", type size:" << sizeof(T) << " Total:" << total << std::endl;
		pointer ptr = (pointer)EDataChunk::instance().allocate(total);
		if (!ptr)
			throw std::exception("fail to allocate memory!!!!");
		return ptr;
	}

	inline void deallocate(pointer _Ptr, size_type _Count){
		EDataChunk::instance().deallocate((char*)_Ptr);
	}

	// construction/destruction
	inline void construct(pointer p, const T& t) {
		new(p) T(t);
	}

	inline void destroy(pointer p) {
		p->~T();
	}
};

简单的内存管理

  1. 一般来说,自己写的内存管理需要自己决定连续地址的内存分配问题,一般称这为多级内存管理, allocate只是其中一级。这里示范一下简单的内存管理
    • 先把申请一块很大的内存
    • 把内存切成一个个固定大小的
    • 每次申请时,遍历找没有使用的块
    • 如果块的大小不够,就往后块连续申请,直到大小足够
struct EDataChunkInfo {
	char* ptr = nullptr;
	int used_count = 0;
};

class EDataChunk {

public:
	
	const int one_chunk_size = 64;

	void init(char* datas, int size) {
		this->all_datas = datas;
		this->total_size = size;
		this->create_data_chunks();
	}

	void uninit() {
		// check all data is release!!!
		for (auto it : this->pages) {
			if (it.used_count != 0)
				throw std::exception("Fail unrelease memory!!!!!");
		}
		this->pages.clear();
		this->all_datas = nullptr;
		this->total_size = 0;
	}

	void create_data_chunks() {
		int cur = 0;
		char* last_ptr = all_datas;
		while (cur + one_chunk_size <= total_size) {
			pages.push_back(EDataChunkInfo{ last_ptr, false });
			last_ptr += one_chunk_size;
			cur += one_chunk_size;
		}
	}

	inline char* allocate(int size) {
		for (auto it = pages.begin(); it != pages.end();) {
			if (it->used_count > 0) {
				it += it->used_count;
			}
			else {
				int cur_size = one_chunk_size;
				int count = 1;
				auto cur_it = it;
				for (; it != pages.end() && cur_size < size; ++it, cur_size += one_chunk_size, ++count) {
					
				}
				if (cur_size >= size) {
					cur_it->used_count = count;
					return cur_it->ptr;
				}	
			}
		}
		return nullptr;
	}

	inline void deallocate(char* ptr) {
		for (auto it = pages.begin(); it != pages.end(); ++it) {
			if (it->ptr == ptr) {
				std::cout << "deallocate memory: "<< it->ptr << ", " << it->used_count << " byte size:" << it->used_count * one_chunk_size << std::endl;
				it->used_count = 0;
				break;
			}
		}
	}

	static EDataChunk& instance() {
		static EDataChunk g_inst;
		return g_inst;
	}

protected:
	std::vector<EDataChunkInfo> pages;
	int total_size = 0;
	char* all_datas = nullptr;
};

使用方式

使用自己写的allocate后

	EDataChunk::instance().init((char*)lpBase, BUFF_SIZE); 
	{
		char* test_ptr = EDataChunk::instance().allocate(sizeof(MyIntVector));
		MyIntVector* test_vec = new(test_ptr) MyIntVector(512, 0);//
		test_vec->resize(10);
		test_vec->push_back(2131);
		test_vec->push_back(21);
		test_vec->push_back(31);
		test_vec->push_back(131);
		test_vec->push_back(213);
		test_vec->~MyIntVector();
		EDataChunk::instance().deallocate(test_ptr);
	}

	EDataChunk::instance().uninit();

结果如下:
do create SharedMemAlloc!!!
trying to SharedMemAlloc allocate:1, type size:8 Total:8
trying to SharedMemAlloc allocate:512, type size:4 Total:2048
Do create shared buff!!!:[0,0,0,0,0,0,0,0,0,0,2131,21,31,131,213]
deallocate memory: 8192128page count: 32, byte size:2048
deallocate memory: 8192064page count: 1, byte size:64
deallocate memory: 8192000page count: 1, byte size:64

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值