|
|
User login
Feeds |
basic - Memory handling
|
|||||
| Thu, 2004-12-16 06:40 | |
|
What does the RunLD function destroy?
Don't I need to do a CleanupStack::PopAndDestroy() after it? Can someone tell me all the important aspects of memory handling and cleanup please? My application ends with a ALLOC + number, and as far as I have understood that means that there are memory leakages. (I have the "Symbian OS C++ for mobile phones" book already) Code: CAknMessageQueryDialog* dlg = CAknMessageQueryDialog::NewL(updateAdrQueryBody); dlg->PrepareLC(R_DIALOG_POPUP_QUERY); dlg->QueryHeading()->SetTextL(updateAdrQueryTitle); if (dlg->RunLD()) { |
|
Forum posts: 33
Regards, Bo
Forum posts: 1379
dlg->PrepareLC(R_DIALOG_POPUP_QUERY); will push your dlg onto the cleanupstack, it will still be there when it returns.
if (dlg->RunLD()) will run your dlg, then finish with a PopAndDestroy.
Likewise dlg->ExecuteLD will both push and pop your dialog (all it does is call PrepareLC followed by RunLD).
didster
Forum posts: 349
Forum posts: 1379
There is only one exception to the rule (that I know of anyway, knowing Nokia there are more undocumented ones) and thats CAknPopupList - it behaves like a dialog (though granted it doesn't derive from any dialog-type class) and it has an ExecuteLD method - probably why people think it is a dialog - but it doesn't do the cleanup stack stuff for you
Probably not relavant since your not using it, but just in case you ever do.
didster
Forum posts: 349
I came to think of another thing that is related:
What about heap descriptors which you use in a dialog which uses RunLD - do you have to use the cleanup stack for them (i e uncommenting the commented rows below)?
HBufC* httpErrorResponseBody = HBufC::NewL(aHttpResponseTxt.DesC().Length());
httpErrorResponseBody->Des().Copy(aHttpResponseTxt.DesC());
TBuf<32> httpErrorResponseTitle = NULL;
iCoeEnv->ReadResource(httpErrorResponseTitle, R_HTTP_ERROR_RESPONSE_TITLE);
//CleanupStack::PushL(httpErrorResponseBody); //Are these destroyed...
//CleanupStack::PushL(httpErrorResponseTitle);
CAknMessageQueryDialog* dlg = CAknMessageQueryDialog::NewL(*httpErrorResponseBody);
dlg->PrepareLC(R_DIALOG_POPUP_ERROR_MESSAGE);
dlg->QueryHeading()->SetTextL(httpErrorResponseTitle);
dlg->RunLD(); //...down here?
//CleanupStack::PopAndDestroy(httpErrorResponseTitle);
//CleanupStack::PopAndDestroy(httpErrorResponseBody);
Also, when you load a resource using, for instance, PrepareLC function - what is really allocated? Let's say I don't use RunLD afterwards, but only use "non-D" functions - how do I make sure the allocated item(s) get removed?
Forum posts: 1379
Basically, these are YOUR pointers - and you can tell that because CAknMessageQueryDialog takes it parameter as a refrence to a descriptor - not a pointer. Therefore it will basically make its own copy of your HBufC. If it did take a pointer, it might take ownership (meaning you dont own your HBufC any more and you don't need to delete it) or it might not (meaning you must still delete it). You can only tell that by reading the docs.
You can actually destroy one of your HBufCs as soon as you have called NewL - it doesn't need to last past the call to RunLD because CAknMessageQueryDialog will take a copy. i.e.
HBufC* httpErrorResponseBody = HBufC::NewLC(aHttpResponseTxt.DesC().Length());
httpErrorResponseBody->Des().Copy(aHttpResponseTxt.DesC());
// dont need the push's because both NewLC and AllocReadResourceLC will put them on the stack
//CleanupStack::PushL(httpErrorResponseBody); //Are these destroyed...
//CleanupStack::PushL(httpErrorResponseTitle);
CAknMessageQueryDialog* dlg = CAknMessageQueryDialog::NewL(*httpErrorResponseBody);
CleanupStack::PopAndDestroy(httpErrorResponseBody);
dlg->PrepareLC(R_DIALOG_POPUP_ERROR_MESSAGE);
dlg->QueryHeading()->SetTextL(httpErrorResponseTitle);
dlg->RunLD();
CleanupStack::PopAndDestroy(httpErrorResponseTitle);
Actually, im not even sure how your compiles with the pushs in....
TBuf<32> httpErrorResponseTitle = NULL;
Thats on the STACK.
Then
CleanupStack::PushL(httpErrorResponseTitle);
That will moan - you can't push non-pointers onto the CleanupStack... (well you can, but you need a TCleanupItem to go with it)
Your best bet is to change it to a HBufC* and read it with AllocReadResourceLC.
If you know its length, you could do it like this:
TBuf<32> httpErrorResponseTitle;
iCoeEnv->ReadResource(httpErrorResponseTitle, R_HTTP_ERROR_RESPONSE_TITLE);
But in that case, httpErrorResponseTitle is on the stack, and wouldn't need to go onto the cleanup stack.
didster
Forum posts: 349
Oh, the T class to the stack was a mistake.
dlg->QueryHeading()->SetTextL(httpErrorResponseTitle);
You told me another time about using a CAknQueryDialog instead of a CAknMessageQuery. Would that be suitable here and if, could you show me how that would look like in this case?
Forum posts: 1379
Depends. Are you asking a simple yes/no true/false type question? And whats the length of the text you are trying to show?
CAknMessageQuery is good for things like "Exit without saving?" etc etc - short snappy questions.
didster
Forum posts: 349
HBufC* httpErrorResponseTitle = iCoeEnv->AllocReadResourceLC(R_HTTP_ERROR_RESPONSE_TITLE);
dlg->QueryHeading()->SetTextL(httpErrorResponseTitle->Des());
Forum posts: 349
Depends. Are you asking a simple yes/no true/false type question? And whats the length of the text you are trying to show?
CAknMessageQuery is good for things like "Exit without saving?" etc etc - short snappy questions.
It is only a dialog of information, user can only press OK.
I also wonder how to deal with this kind of issue:
HBufC8* aSmsNumber = ....some initialization
HBufC8* aSmsNr = HBufC8::NewL(pBuf8->Length() + aSmsNumber->Length());
aSmsNr->Des().Append(pBuf8->Des());
aSmsNr->Des().Append(aSmsNumber->Des());
What should be deleted here? Only aSmsNr, pBuf8 and aSmsNumber or all of them?