C++ 内存管理03-内存池01

内存池01

通过我前面的讲解,你已经知道每调用malloc一次都会产生cookie或者其他消耗资源的东西,它们是占用内存的,总之,减少malloc 的调用总是好的。于是为了解决这个问题,内存池出场了。
假设你需要new 1000个对象,如果执行new 1000次,显然就意味着会执行malloc 1000次,而产生额外的资源比如cookie也就有1000次,而包含上下两个cookie,分别占4个字节。那1000次光cookie就占用2 x 4 x 1000 bytes. 所以现在的改进是一次new 1000个对象,new object[1000],那么此次只执行了一次malloc。其实这就是内存池。内存管理的目标也就是速度和空间。
接下来我们实现这个例子,并且作对比。请看代码。

class foo{
public:
	foo() :a(0)
	{
		
		cout << "默认构造函数\n";
	}
	foo(int x)
	{		
		a = x;		
		cout << "a:" << a << endl;
	}
	static void *operator new(size_t size)
	{
		foo *p = NULL;
		if (!freestore)
		{
			size_t chunk = size*ncount;
			//一次获得ncount个对象大小的空间
			freestore = p = reinterpret_cast<foo *>(new char[chunk]);
			for (int i = 0; i < ncount;i++)
			{
				
				p->next = p+1;
				p++;
			}
			p->next = NULL;
		}
		//将要返回的内存用p接管
		p = freestore;
		//为了下一次获得内存做准备,指针下移
		freestore = freestore->next;
		return p;
	}
	
	static void operator delete(void *p)
	{
		//将回收的内存放到头节点。
		(static_cast<foo *>(p))->next = freestore;
		
		//将第一个内存指向回收的内存
		freestore = static_cast<foo *>(p);
		
	}

	
	~foo()
	{
		cout << "~foo()\n";
	}
public:
	int a;
	//int b;
	foo *next{NULL};
	static const int ncount;
	static foo *freestore;
};

const int foo::ncount = 24;
foo *foo::freestore = NULL;

void main()
{
	cout << sizeof(foo) << endl;
	
	foo *afoo[10];
	for (int i = 0; i < 10;i++)
	{
		afoo[i] = new foo(i + 1);
	}
	cout << "--------------华丽的分割线-----------------\n";
	for (int i = 0; i < 10;i++)
	{
		cout << afoo[i] << endl;
	}

	for (int i = 0; i < 10;i++)
	{
		delete afoo[i];
	}
	system("pause");
}

看结果(重载new):
在这里插入图片描述
可以看到间隔为8.
看结果(没有重载new):
在这里插入图片描述
间隔48,上一节我们讲了,malloc的时候会产生一个32位字节的包,和两个上下cookie (占8个字节),在加类大小为8 故间隔为48.
但是这里还有一个问题,额外增加了一个指针next,它占用4个字节,到低值不值呢?或者该如何改进呢,欲知后事,请听下回!

发布了65 篇原创文章 · 获赞 6 · 访问量 1570

猜你喜欢

转载自blog.csdn.net/FairLikeSnow/article/details/103152189
今日推荐