C++内存池

参考SGI-STL实现的内存池头文件,代码不过一百来行,非常简单。

为了简化代码,做了如下改动:

  1. 取消错误处理(错误处理主要在内存申请失败上,现在电脑内存都很大,基本不存在申请不到内存的情况)
  2. 取消 remalloc ,只提供 mallocfree 两个接口

内存池源码:

#pragma once
#include<cstdlib>

class TAmempool {
private:
	enum {UNIT=8};
	enum {MAXSIZE=128};
	enum {LISTLEN=MAXSIZE/UNIT};
	union listnode {
		union listnode* next;
		char memaddr[1];
	};
	static listnode* volatile listheadarr[LISTLEN];
	static  char* end_free;
	static  char* start_free;
	static  size_t heap_size;

	/*align the user's memunit size*/
	static size_t round_up(size_t bytes) {
		return (bytes + UNIT-1) & ~(UNIT - 1);//!!!!!
	}
	/*to get the position fo the mem block of this size*/
	static size_t getlistindex(size_t bytes) {
		return (bytes + UNIT - 1) / UNIT - 1;
	}

	static void* refill(size_t n) {
		int nodenum = 20;
		char* chunk = chunkalloc(n, nodenum);
		if (nodenum == 1) {
			return chunk;
		}

		listnode* volatile* listhead;
		listnode* result;
		listnode* current_node;
		listnode* next_node;


		listhead = listheadarr + getlistindex(n);
		*listhead = next_node = (listnode*)(chunk + n);
		
		//TODO:this loop needs to be simplyfy
		//for (int i = 1;; i++) {
		//	current_node = next_node;
		//	next_node = (listnode*)((char*)next_node + n);
		//	if (nodenum - 1 == i) {
		//		current_node->next = 0;
		//		break;
		//	} else {
		//		current_node->next = next_node;
		//	}
		//}

		for (int i = 1; nodenum - 1 != i; i++) {
			current_node = next_node;
			next_node = (listnode*)((char*)next_node + n);
			current_node->next = next_node;
		}
		current_node = next_node;
		next_node = (listnode*)((char*)next_node + n);
		current_node->next = 0;

		return (listnode*)chunk;
	}

	static char* chunkalloc(size_t nodesize, int& nodenum) {

		size_t total_bytes = nodesize * nodenum;
		size_t bytes_left = end_free-start_free;
		char* result;

		//TODO:too complicated
		if (bytes_left >= total_bytes) {
			result = start_free;
			start_free += total_bytes;
			return result;
		} else if (bytes_left >= nodesize) {
			nodenum = bytes_left / nodesize;
			total_bytes = nodesize * nodenum;

			result = start_free;
			start_free += total_bytes;
			return result;//!!!!!
		} else {
			//将剩余的一点内存分配到最合适的地方去
			size_t bytes_to_get = 2 * total_bytes + round_up(heap_size >> 4);
			if (bytes_left > 0) {
				listnode* volatile* listhead = listheadarr + getlistindex(bytes_left);
				((listnode*)start_free)->next = *listhead;
				*listhead = (listnode*)start_free;
			}

			//从系统申请新的内存
			start_free = (char*)std::malloc(bytes_to_get);
			end_free = start_free + bytes_to_get;
			heap_size += bytes_to_get;

			return chunkalloc(nodesize, nodenum);
		}
	}



public:
	static void* malloc(size_t n) {
		listnode* volatile* listhead;
		listnode* result;

		if (n > (size_t)MAXSIZE) {
			return std::malloc(n);
		}
		listhead = listheadarr + getlistindex(n);
		result = *listhead;
		if (result == 0) {//? where the 0 come from?
			return refill(round_up(n));
		}
		*listhead = result->next;
		return result;
	}

	static void free(void *p,size_t n) {
		listnode* q = (listnode*) p;
		listnode* volatile* listhead;

		if (n > (size_t)MAXSIZE) {
			std::free(p);//为了不与本类中的free冲突
			return;

		}

		listhead = listheadarr + getlistindex(n);

		q->next = *listhead;
		*listhead = q;
	}
};

TAmempool::listnode* volatile TAmempool::listheadarr[LISTLEN] = { 0 };
char*  TAmempool::end_free = 0;
char*  TAmempool::start_free = 0;
size_t TAmempool::heap_size = 0;

测试源码:

#include<iostream>

#include "TAmempool.h"
using namespace std;

#include<ctime>
class TAtimer {
	clock_t startTime;
	clock_t endTime;
public:
	void start() {
		startTime = clock();
	}
	void stop() {
		endTime = clock();
	}
	float getS() {
		return float(endTime - startTime) / CLOCKS_PER_SEC;
	}
	clock_t get() {
		return (endTime - startTime);
	}
};
int main() {
	TAmempool pool;
	int** x;
	int t=0;
	x = new int* [10000];
	TAtimer timer;
	for (int m = 0; m < 10; m++) {
		timer.start();
		for (int j = 1; j < 200; j++) {
			for (int i = 0; i < 10000; i++) {
				//cout << i<<" ";
				x[i] = (int*)pool.malloc(sizeof(int));
			}
			for (int i = 0; i < 10000; i++) {
				pool.free(x[i], sizeof(int));
			}
		}

		timer.stop();
		cout << timer.get() << endl;
		t += timer.get();
	}
	cout <<endl<< t /10;

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值