item26判斷對象是否在堆中

#include <iostream>

using namespace std;
/*判斷某個對象是否在heap*/
class A{
public:
	A() ;
	class NoOnHeap;
	A(int ) { }
	static void* operator new(size_t size);
	void destroy() { delete this;}
protected:	//for B
	static bool isOnHeap;
	~A() { }//defined must be  
};
bool isOnHeap = false;
A::A()
{
	if(!isOnHeap)
		
		throw NoOnHeap();
	else
		A(int);//一個正常的ctor,new不是正常的
		isOnHeap = false;
}

void* operator new(size_t size)
{
	isOnHeap = true;
	return ::operator new(size);
}

/*不行的原因:判斷位在有些情況下不能預期工作
1 operator new[],new是分配一塊內存,ctor來賦值
所以就算你有記得把判斷位重置也沒用,因爲它就用一次new
2 A* pa = new(*new A) 理想狀態下是 new - ctor - new - ctor
但實際上是 new new ctor ctor
*/

bool onHeap(const void* address)
{
	char onStack;
	return address < &onStack;
}
/*安妮他們在函數作用域中出現的次序來分配他們在棧中位置、但考慮static
一切就不對了,當想盡辦法去加上if static的方法時,又要考慮不可移植,這時候
就要重新考慮是不是判斷是否在堆中就是一個錯誤的思想,書上說,一般上client
都是想delete安全指針。但值得注意的是,delete this聲名狼藉*/

/*且是否安全得delete 指針 與 是否在堆上並沒有關係*/

void main()
{
	C* c = new C;
	delete c;
	//哦哦,他把 A* vaule ==> A vaule 這樣就是爲了讓它沒有析構函數調用
}

class HeapTracked//足跡
{
public:
	HeapTracked();
	class missAddress;//用以拋出
	virtual ~HeapTracked() = 0;
	static void* operator new (size_t size);
	static void operator delete (void *ptr);
	bool isOnHeap();
private:
	typedef const void* rawMemory;
	list<rawMemory> addresses;
};

void * HeapTracked::operator new (size_t size)
{
	void* address = ::operator new(size);
	addresses.push_front();//頭部?
	return address;address
}

void HeapTracked::operator delete(void *ptr)
{
	list<rawMemory>::const_iterator it = 
		find(addresses.begin(), addresses.end(), ptr);
	if(it != addresses.end())
	{	addresses.erase(it);
		::operator delete ptr;
	}
	else
	{
		throw missAddress();
	}
}

bool HeapTracked::isOnHeap()
{
	const void * rawAddress = dynamic_cast<const void*>(this);
	//取得一個指針,指向 *this 所佔內存的起始處,我想不到的一部

	list<rawMemory>::iterator it = 
		find(addresses.begin(), addresses.end(), rawAddress);

	return it != addresses.end();
}


發佈了60 篇原創文章 · 獲贊 4 · 訪問量 1萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章