basic - Memory handling

Login to reply to this topic.
Thu, 2004-12-16 06:40
Joined: 2004-09-06
Forum posts: 349
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()) {

Thu, 2004-12-16 23:01
Joined: 2004-11-21
Forum posts: 33
Re: basic - Memory handling
Quote from: joape382
What does the RunLD function destroy?
The dlg object.
Quote from: joape382
Don't I need to do a CleanupStack::PopAndDestroy() after it?
No, but not knowing the interface would lead you to putting in a CleanupStack::Pop instead, which you shouldn't either in this case.  But I'm not 100% sure on this one. Comments anybody?

Regards, Bo

Fri, 2004-12-17 08:56
Joined: 2004-07-28
Forum posts: 1379
basic - Memory handling
No Pop's, no PopAndDestroys.

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

Fri, 2004-12-17 10:04
Joined: 2004-09-06
Forum posts: 349
basic - Memory handling
Thanks a lot didster!
Fri, 2004-12-17 10:14
Joined: 2004-07-28
Forum posts: 1379
basic - Memory handling
No problem.

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 Smiley There is a explination in aknpopup.h.

Probably not relavant since your not using it, but just in case you ever do.

didster

Fri, 2004-12-17 10:31
Joined: 2004-09-06
Forum posts: 349
basic - Memory handling
Great!

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)?

Code:
//HTTP error returned - display it
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?
Fri, 2004-12-17 10:42
Joined: 2004-07-28
Forum posts: 1379
basic - Memory handling
Ok.

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.

Code:
HBufC* httpErrorResponseTitle = iCoeEnv->AllocReadResourceLC(R_HTTP_ERROR_RESPONSE_TITLE);

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

Fri, 2004-12-17 11:01
Joined: 2004-09-06
Forum posts: 349
basic - Memory handling
Thanks,

Oh, the T class to the stack was a mistake.

Code:
HBufC* httpErrorResponseTitle = iCoeEnv->AllocReadResourceLC(R_HTTP_ERROR_RESPONSE_TITLE);
dlg->QueryHeading()->SetTextL(httpErrorResponseTitle);
gives me a compiling error.

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?
Fri, 2004-12-17 11:05
Joined: 2004-07-28
Forum posts: 1379
basic - Memory handling
Quote from: joape382
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?

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

Fri, 2004-12-17 11:05
Joined: 2004-09-06
Forum posts: 349
basic - Memory handling
Ah, of course... doing like this will work

HBufC* httpErrorResponseTitle = iCoeEnv->AllocReadResourceLC(R_HTTP_ERROR_RESPONSE_TITLE);
dlg->QueryHeading()->SetTextL(httpErrorResponseTitle->Des());
Fri, 2004-12-17 11:07
Joined: 2004-09-06
Forum posts: 349
basic - Memory handling
Quote from: didster
Quote from: joape382
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?

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:

Code:
HBufC8* pBuf8 = ....some initialization
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?
  • Login to reply to this topic.