栈空间也存放在堆上创建的对象的指针,但发生异常的时候,在栈上创建的会自动被释放,同时在栈上存放的指
向堆上的指针也同时被释放了,故堆上创建的对象失去了指向他的指针,不能释放而产生内存泄露。
这种情况可以用清除栈来避免
……
CMyclass* myObject = new CMyclass;
CleanupStack::PushL(myObject);
…………
CleanupStack::Pop();
delete myObject:
//也可以用CleanupStack::PopAndDestroy()
//弹出并销毁
//或者有多个对象的时候,CleanupStack::PopAndDestroy(2);
//弹出并销毁多个
………………
可以压入清除栈的对象包括:TAny*,CBase*和TCleanupItem;
压入一切C类对象指针时,清除栈都将视为CBase*的变量,这是清除栈最常用的做法。
对象必须以严格的顺序压入和弹出清除栈,一组Pop()操作必须与PushL()调用的顺序相反。
当然,也可以直接CleanupStack::PopAndDestroy(n);
对于一个对象,清除永远不要超过一次。
永远不要将类成员变量压入清除栈,会导致double-deletion
如果有对象被压入清除栈,并直至函数返回时还保留在清除栈上,则该函数应该以”C”作为后缀。这就告诉函数调
用者,如果函数正常返回,清除栈上仍然有多余的对象。
如:两阶段构造中的NewlC()函数
CClassName::NewLC()
{
CCLassName* myObject=new(ELeave)CCLassName;
CleanupStack::PushL(myObject);
myObject->ConstructL();
return myObject;
}
CCLassName::NewL()
{
CCLassName* myObject=CClassName::newLC();
myObject->Pop();
return myObject;
}
所以,要是使用NewL的话,就要记得销毁,要是使用NeWLC的话,就要记得弹出,销毁!