The cleanup stack is used as follows:
Use CleanupStack::PushL()
to push a
pointer to the object onto the cleanup stack before any operation which might
leave is performed
Use CleanupStack::PopL()
to pop the pointer from the
cleanup stack when all operations that might leave have completed
If a function leaves, then part of leave processing is to pop and destroy all objects on the cleanup stack. Thus, the cleanup stack may be used to prevent objects becoming orphaned if a leave occurs.
void doExampleL()
{
// allocate with checking
CExample* myExample = new (ELeave) CExample;
// do something that cannot leave
myExample->iInt = 5; // cannot leave: no protection needed
// do something that can leave: use cleanup stack
CleanupStack::PushL(myExample); // pointer on cleanup stack
myExample->DoSomethingL(); // something that might leave
CleanupStack::Pop(); // it didn't leave: pop the pointer
// delete
delete myExample;
}
The cleanup stack is necessary here because the
CExample
would be orphaned on the heap if a leave occurred. This
is because the CExample
is referred to only by an automatic
pointer myExample
, which itself becomes orphaned on the stack when
the leave occurs. If the CExample
’s address had been stored
in an object which was not orphaned by the leave, then it
would not be necessary to use the cleanup stack to ensure that it is cleaned up
correctly.
The CleanupStack::PushL()
operation itself may
leave — because more memory may be needed for more cleanup stack
frames. It is guaranteed that the object is pushed to the stack before any
attempt is made to allocate more stack space. Thus, a failure of
CleanupStack::PushL()
will cause the object that was being pushed
to be cleaned up properly.