一个最简单的内存池AutoMemory

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/marising/article/details/52242000

    C/C++中内存管理是个最麻烦的事情,内存申请释放,内存泄露,内存越界,甚至是内存碎片,就会导致程序出Core或者变慢。如何有效的管理内存,有很多方法,我认为最简单的方式是用一个内存池来管理内存。

    谈到内存池的时候,就有必要说下程序的生命周期和作用域,数据分为三类:1类是进程数据(全局数据)。2、线程数据,每一个线程一份。3、请求数据,每一次调用一份。

        

    如果一个内存池想什么生命周期和作用域的数据都放在里面,可能是不合适的。所以我建议的使用方式是:进程一个内存池、每一个线程一个内存池、每个请求一个内存池。

    在进程/线程/请求初始时初始内存池,在进程/线程/请求结束时销毁内存池。

    所以,就有了下面这个非常简单的内存池了,代码有一点点绕,不过仔细阅读还是能理解的。

    头文件 AutoMemory.h

#ifndef _AUTO_MEMORY_H__
#define _AUTO_MEMORY_H__

#include <stddef.h>

//#define _MEM_TEST_
//#define _MEM_DEBUG_
#define _MEM_USE_

//default 1M
#define MEMORY_BLOCK_SIZE 1000000


/*
 * 线程兼容,自动释放
 */
class AutoMemory
{
public:
	AutoMemory();
	AutoMemory(int block_size);
	~AutoMemory();
	void* Alloc(size_t size);
	void Free(void* ptr);
	void FreeAll();

	void Debug();
	int BlockCount();
	size_t LeftSize();
	size_t MemSize();

private:
	struct MemBlock{
		MemBlock* prev;
	};
private:
	int headerSize;
	int blockSize;
	size_t memSize;
	int blockCount;
	char* begin;
	char* end;
	//MemBlock* currBlock;
};

#endif

   CPP文件AutoMemory.cpp

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "AutoMemory.h"

AutoMemory::AutoMemory(){
	blockSize =  MEMORY_BLOCK_SIZE;
	blockCount = 0;
	memSize = 0;
	headerSize = sizeof(MemBlock);
	begin = end = ( char* ) headerSize;
}

AutoMemory::AutoMemory(int block_size){
	blockSize =  block_size;
	blockCount = 0;
	memSize = 0;
	headerSize = sizeof(MemBlock);
	begin = end = ( char* ) headerSize;
}

AutoMemory::~AutoMemory(){
	FreeAll();
}

size_t AutoMemory::MemSize(){
	return memSize;
}

int AutoMemory::BlockCount(){
	return blockCount;
}

size_t AutoMemory::LeftSize(){
	return (size_t)(end-begin);
}

void AutoMemory::Debug(){
	printf("Block count %d, Left size %d, Total size %d\n",
			this->BlockCount(),
			this->LeftSize(),
			this->MemSize() );
}

void* AutoMemory::Alloc(size_t size){
#ifndef _MEM_USE_
	return malloc(size);
#endif

	if ( (size_t)( end - begin ) < size ){
		if ( size >= blockSize){
			char* ptr = (char*)malloc(headerSize + size);
			MemBlock* pNew = (MemBlock*)ptr;
			MemBlock* pHeader = (MemBlock*)(begin - headerSize);
			if ( pHeader ){
				pNew->prev = pHeader->prev;
				pHeader->prev = pNew;
			}else{
				end = begin = (char*)( ptr + headerSize );
				pNew->prev = NULL;
			}
			blockCount += 1;
			memSize += size;
			return end;
		} else{
			char* ptr = (char*)malloc(headerSize + blockSize);
			MemBlock* pNew = (MemBlock*)ptr;
			pNew->prev = (MemBlock*)(begin - headerSize);
			begin = (char*)(ptr + headerSize);
			end = begin + blockSize;
			blockCount += 1;
			memSize += blockSize;

		}
	}
	return end -= size;
}

void AutoMemory::Free(void* ptr){
#ifndef _MEM_USE_
	free( ptr );
#endif
}

void AutoMemory::FreeAll(){
	MemBlock* pHeader = (MemBlock*)(begin - headerSize);
	while( pHeader ){
		MemBlock* pTemp = pHeader->prev;
        free( pHeader );
		pHeader = pTemp;
	}
	begin = end = (char*)headerSize;
	memSize = 0;
	blockCount = 0;
}

#ifdef _MEM_TEST_
int main(){
	AutoMemory am(100);
	printf("idx 1, alloc 10\n");
	char* buf = (char*)am.Alloc(10);
	am.Debug();

	printf("idx 2, alloc 90\n");
	am.Alloc(90);
	am.Debug();

	printf("idx 3, alloc 10\n");
	am.Alloc(10);
	am.Debug();

	printf("idx 4, alloc 100\n");
	am.Alloc(100);
	am.Debug();

	printf("idx 5, alloc 10\n");
	am.Alloc(10);
	am.Debug();
}
#endif





阅读更多
换一批

没有更多推荐了,返回首页