Cleanups stack is needed to store the pointers to the objects created, so that they could be deleted in case of a leave.
Consider the below pseudo code.
--------------------------8<---------------------------
void Function1L()
{
TRAPD(err,Function2L());
}
void Function2L()
{
CObject* myObj=new (ELeave) CObject; //Create some object
CleanupStack::PushL(myObj); //Push it on the cleanup stack
Function3L(); // Call some leaving function
CleanupStack::PopAndDestroy(); //Destroy the created object
}
void Function3L()
{
//Some code which leaves
}
--------------------------8<---------------------------
When the above code is executed, it leaves in Function3. What happens to the memory allocated to myObj? If we did not have the cleanupstack, then the pointer to the myObj object would not be available. So the memory pointed by myObj would be lost forever. So, for this very reason, the cleanup stack is used. The cleanup stack acts as a location for storing pointers, which can be deleted in case there is a leave.
The symbian provides two trap harnesses TRAP and TRAPD. Whenever a leave happens, the control goes back till the Trap. Now, in the above pesudo code, when Function3L() leaves, the control goes till the innermost Trap and the cleanupstack unwinds till that point. All the objects that were pushed on the stack the stack since the beginning of the Trap are poped and destroyed. So, in this case, myObj is popped from the stack and then destroyed.