more-effective-c++ 序列1 new和delete的测试

more-effective-c++ 序列1 new和delete的测试


1,在堆内存中分配对象,而且欲对堆内存的分配使用自己的方式。

Widget *pWidget = new Widget():
1,调用operator new 分配内存
2,将内存上的对象调用构造函数
3,转换为Widget*赋值给pWidget
故而可以通过重写operator new 和delete来自己决定内存分配方式。


下面的代码在operator new中调用的malloc,在operator delete 调用的free。
当然你甚至可以使用内存池的观点,operator new调用GetMemory, operator delete调用ReturnMemory.
这样可以个性化自己的内存分配方式。
#include <iostream>
using namespace std;


/*
new operator会调用operator new和Widget的构造函数
重载operator new和delete可以订制自己的行为。
*/
#define TRACE_FUCTION_AND_LINE(fmt, ...) printf("[%20s:%4d]"fmt"\n",__FUNCTION__, __LINE__, ##__VA_ARGS__)
class Widget
{
public:
	Widget(){TRACE_FUCTION_AND_LINE();}
	void* operator new(size_t nSize)
	{
		void*p =  malloc(sizeof(Widget));
		TRACE_FUCTION_AND_LINE("malloc p=%08p", p);
		return p;
	}
	void operator delete(void* memory)
	{
		TRACE_FUCTION_AND_LINE("free p=%08p", memory);
		free(memory);
	}
	~Widget(){TRACE_FUCTION_AND_LINE();}
};
int main()
{
	Widget *pWidget = new Widget();
	TRACE_FUCTION_AND_LINE("begin to delete");
	delete pWidget;
	return 0;
}





2. 打算在已经分配的内存上分配对象,使用placement new的方式



下面的代码main函数中,首先分配了一个栈内存buf,然后赋值给memory指针。
然后调用new (memory)Widget(100)将memory指针传递到operator new 方法。
由于operator new是为了分配内存的,现在已经有一个栈内存了,可以直接拿来使用,故而直接return buffer;
然后会调用Widget的构造函数初始化对象。打印日志后需要执行调用对象的析构函数。
如果不主动调用析构函数,那么对象的析构函数就不会被调用。
也许你会问,为什么不调用delete pw来释放内存呢?你可以尝试一下,由于operator delete默认会采用delete方式delete内存,这样实际上delete的是
栈内存memory,这会立刻出现问题。


main函数下面注释的一段代码仅仅是个人对new,operator new,malloc三种内存分配和释放方式的简单测试,就想看看哪个效率更高一点。
测试例子不够完善,一般的内存使用方案的分配和释放都是随机的,这个例子不是,不能准确的反映现实数据,但至少说明了malloc似乎更快一点。

#include <iostream>
#include <time.h>
using namespace std;


/*
new operator会调用operator new和Widget的构造函数
重载operator new和delete实现placement new
*/
#define TRACE_FUCTION_AND_LINE(fmt, ...) printf("[%20s:%4d]"fmt"\n",__FUNCTION__, __LINE__, ##__VA_ARGS__)
class Widget
{
public:
	Widget(int nHight = 0): m_nHight(nHight) {TRACE_FUCTION_AND_LINE();}
	void* operator new(size_t nSize, void* buffer)
	{
		TRACE_FUCTION_AND_LINE("malloc p=%08p", buffer);
		return buffer;
	}
	~Widget(){TRACE_FUCTION_AND_LINE();}
	void Log () {TRACE_FUCTION_AND_LINE("My Log------%d", m_nHight);}
	int m_nHight;
};
int main()
{
	char buf[sizeof(Widget)]; //分配栈内存
	void* memory = buf;//分配widget内存,实际上使用的是栈内存
	TRACE_FUCTION_AND_LINE("memory = %08p", memory);
	Widget* pw = new (memory)Widget(100); //placement new 将memory指针传递到operator new
	pw->Log();
	
	pw->~Widget();//主动调用析构函数


	/*
	double start, end;
	while(1)
	{
	start = clock();
	for(int i = 0; i < 500; ++i)
	{
		for(int j = 0; j < 10000; ++j)
		{
			void* pMemory = operator new(10000);
			operator delete(pMemory);
		}
	}
	end = clock();
	TRACE_FUCTION_AND_LINE("operator new takes %.2f seconds", (end-start) / CLOCKS_PER_SEC);
	
	start = clock();
	for(int i = 0; i < 500; ++i)
	{
		for(int j = 0; j < 10000; ++j)
		{
			void* pMemory = new char[10000];
			delete [](pMemory);
		}
	}
	end = clock();
	TRACE_FUCTION_AND_LINE("new char takes %.2f seconds", (end-start) / CLOCKS_PER_SEC);


	start = clock();
	for(int i = 0; i < 500; ++i)
	{
		for(int j = 0; j < 10000; ++j)
		{
			void* pMemory = malloc(10000);
			free(pMemory);
		}
	}
	end = clock();
	TRACE_FUCTION_AND_LINE("malloc takes %.2f seconds", (end-start) / CLOCKS_PER_SEC);
	TRACE_FUCTION_AND_LINE("\n\n\n");
	}
	*/
	return 0;
}


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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值