当前位置: 首页 > 工具软件 > MemoryPool > 使用案例 >

MemoryPool内存池(二)

计均
2023-12-01

前面对内存池已经有了一个大致的复习,现在实现一个简单的固定内存池
   
一、MemoryPool.h

#ifndef __SOFT_COLLECTION_H__
#define __SOFT_COLLECTION_H__

#include <iostream>
#include <string>
#include <errno.h>
#include <unistd.h>
#include <stdint.h>
#include <memory.h>

#define MEMPOOL_ALIGNMENT 8

struct memory_block
{
	//参数直接赋值
	memory_block(unsigned short type = 1, unsigned short unit_size = 0);
	virtual ~memory_block(){};
		
	unsigned short size;
	unsigned short free;
	unsigned short first;
	//unsigned short dummy_align;
	
	memory_block* next;
	char data[1];
	
		
	static void* operator new(size_t, unsigned short type, unsigned short unit_size)
	{
		return ::operator new(sizeof(memory_block) + type * unit_size);
	}
	
	static void operator delete(void* p, size_t)
	{
		::operator delete(p);
	}
};
	
class memory_pool
{
public:
	//第一个参数动态分配(构建对象时分配),后两个参数直接赋值
	memory_pool(unsigned short _unit_size, unsigned short _init_size = 1024, unsigned short _grow_size = 256);
	virtual ~memory_pool();
	void* alloc();
	void free(void* _free);

	//void safety_alloc();
	void safety_free(void* _pfree);
	
	memory_block* new_init_block() const
	{
		return new(init_size, unit_size) memory_block(init_size, unit_size);
	}
	memory_block* new_grow_block() const
	{
		return new(grow_size, unit_size) memory_block(grow_size, unit_size);
	}
	
		
private:
	memory_block* block;
	unsigned short unit_size;
	unsigned short init_size;
	unsigned short grow_size;
};

#endif

二、MemoryPool.cpp

#include "MemoryPool.h"
#include <pthread.h>
#include <unistd.h>

memory_block::memory_block(unsigned short type, unsigned short unit_size)
		:size(type * unit_size),
		 free(type - 1),
		 first(1),
		 next(0)
{
	char* _data = data;
	for(unsigned short i = 1; i < type; ++i)
	{
		*reinterpret_cast<unsigned short*>(_data) = i;
		_data += unit_size;
	}

}

memory_pool::memory_pool(unsigned short _unit_size, unsigned short _init_size, unsigned short _grow_size)
		:block(nullptr),
		 unit_size(_unit_size),
		 init_size(_init_size),
		 grow_size(_grow_size)
		
{
	if(_unit_size <= 2)
	{
		unit_size = 2;
	}
	else if(_unit_size > 4)
	{
		unit_size = (_unit_size + (MEMPOOL_ALIGNMENT - 1)) & ~(MEMPOOL_ALIGNMENT - 1);
	}
	else
	{
		unit_size = 4;
	}
}

memory_pool::~memory_pool()
{
	memory_block* _block = block;

	while(_block)
	{
		memory_block* temp  = _block->next;
		delete _block;
		_block = temp;
	}
}


void* memory_pool::alloc()
{	
	if(!block)
	{
		block = new_init_block();
		if(!block)
			return nullptr;
		return (void*)(block->data);
	}

	memory_block* _block  = block;
	while(_block && !_block->free)
	{
		_block = _block->next;
	}

	if(_block)
	{
		char* _free = _block->data + (_block->first * unit_size);
		_block->first = *((unsigned short*)_free);
		_block->free--;
		return (void*)_free;
	}
	else
	{
		if(grow_size)
			return nullptr;
		_block = new_grow_block();

		if(!block)
			return nullptr;

		_block->next = block->next;
		block->next = _block;

		return (void*)(_block->data);
	}
}

	
void memory_pool::free(void* _free)
{	
	memory_block* _block = block;
	memory_block* prev = nullptr;
	while(((unsigned long)_block->data > (unsigned long)_free) ||
			((unsigned long)_free >= ((unsigned long)_block->data + _block->size)))
	{
		prev = _block;
		_block = _block->next;

		if(!_block)
			return;
	}

	_block->free++;
	*((unsigned short*)_free) = _block->first;
	_block->first = (unsigned short)(((unsigned long)_free - (unsigned long)(_block->data)) / unit_size);

	if(prev && (_block->free * unit_size == _block->size))
	{
		prev->next = _block->next;
		delete _block;
	}
	else
	{
		if(prev)
		{
			prev->next = _block->next;
			_block->next = block->next;
			block->next = _block;
		}	
	}
}	

 类似资料: