There is a question about HBufC* on the ReAlloc() memory allocation

Login to reply to this topic.
Mon, 2007-09-17 05:15
Joined: 2007-09-17
Forum posts: 11

The source is :

CConsoleBase* console;
_LIT(KString1,"HBufC_test");
//#define _LIT(name,s) const HLitC name = {sizeof(s)-1,s}
_LIT(KString2,"My Heap String");
_LIT(KName,"HBufC_test");

void RunConsoleL()
{
HBufC* myHeapDes = HBufC::NewL(KString1().Length());
CleanupStack::PushL(myHeapDes);
*myHeapDes = KString1;

console = Console::NewL(KName,TSize(KConsFullScreen,KConsFullScreen));
CleanupStack::PushL(console);
_LIT(KFromat1,"myHeapDes = \"%S\"\nlength = %d\n");
console->Printf(KFromat1,myHeapDes,myHeapDes->Length());


myHeapDes->ReAllocL(KString2().Length()); Puzzled
//Replace entire string in the HBufC
*myHeapDes = KString2;
console->Printf(KFromat1,myHeapDes,myHeapDes->Length());

//Get a modifiable pointer to the HBufC's data buffer
TPtr myPtr = myHeapDes->Des();//
_LIT(KString3,"Hello");
_LIT(KString4,"!!!");
//Modifiable the HBufC buffer area through the TPtr,using Copy() and Append()

myPtr.Copy(KString3);
myPtr.Append(KString4);
_LIT(KFromat2,"myHeapDes = \"%S\"\nlength = %d\n myPtr = \" %S \"\nLength = %d\n");
console->Printf(KFromat2,myHeapDes,myHeapDes->Length(),&myPtr,myPtr.Length());
console->Getch();
CleanupStack::PopAndDestroy(myHeapDes);
}

TInt E32Main()
{
__UHEAP_MARK;
CTrapCleanup* CleanupStack = CTrapCleanup::New();
TRAPD(error,RunConsoleL());
__ASSERT_ALWAYS(!error,User::Panic(_L("Example"),error));
delete CleanupStack;
__UHEAP_MARKEND;
return 0;
}
when this program runing in the myHeapDes->ReAllocL(....),then PANIC,
I don't WHY?
can you tell me why so that?thanks


i'm a student,you are my teacher.


Mon, 2007-09-17 07:36
Joined: 2004-05-21
Forum posts: 285
Re: There is a question about HBufC*

What is the panic code? Other thing what you have to do is after myHeapDes->ReAllocL you have to pop and push myHeapDes in to cleanupstack as the address might have changed.

Cheers,
Sri

Mon, 2007-09-17 07:58
Joined: 2007-04-29
Forum posts: 51
Re: There is a question

not painc at the point of " myHeapDes->ReAllocL", but at the line, "*myHeapDes = KString2;"

modify

myHeapDes->ReAllocL(KString2().Length()); 
//Replace entire string in the HBufC
*myHeapDes = KString2;

as belowing

HBufC* newBuffer = myHeapDes->ReAllocL(KString2().Length()); 
CleanupStack::Pop(myHeapDes);
CleanupStack::)PushL(newBuffer);  //NOTICE: don't forget to call CleanupStack::Pop(newBuffer) at appropiate line
//Replace entire string in the HBufC
*newBuffer = KString2;

Mon, 2007-09-17 12:10
Joined: 2007-09-17
Forum posts: 11
Re: There is a question

To mickeyfirst:
Sorry ,it is still or erroneous,I tried you method.
i think if you allocate a new object (HBufC* newBuffer) ,maybe it is waste memory,
THANKS very much!


i'm a student,you are my teacher.

Mon, 2007-09-17 13:44
Joined: 2005-11-20
Forum posts: 1156
Descriptor FAQ

I can recommend the "Descriptor FAQ" at
http://descriptors.blogspot.com/2005/05/20-how-do-i-use-heap-based-buffer.html

At huangfangcheng: ReAllocL can't possibly lead to waste of memory, because the old memory is freed, regardless of what you do with the new pointer.

I think the only problem with your original code is the fact that you don't store the return value of ReAllocL, as this return value is the (possibly) new pointer to the re-allocated HBufC, and without that of course it does not work.

At mickeyfirst: I dont' think that the CleanupStack is a problem when working with ReAllocL. I think that the CleanupStack does not store the pointer to the allocated memory, but a pointer to (i.e. the address of) myHeapDes itself. Check the sample code in the Descriptor FAQ using ReAllocL: There is no Pop/Re-PushL there...


René Brunner

Mon, 2007-09-17 15:28
Joined: 2007-09-17
Forum posts: 11
Re: There is a question about HBufC*

I got it,
like that it's OK!

myHeapDes = myHeapDes->ReAllocL(KString2().Length());//if you do not do this,next line would panic
        //Replace entire string in the HBufC
        *myHeapDes = KString2;
        console->Printf(KFromat1,myHeapDes,myHeapDes->Length());

Thanks


i'm a student,you are my teacher.

Tue, 2007-09-18 02:34
Joined: 2007-04-29
Forum posts: 51
Re: There is a question

Hi huangfangcheng

I consider your method is same as mine.

when you test my codes , maybe you did not modify *myHeapDes = KString2; as *newBuffer = KString2;

Because the root cause of your problem is: when calling ReAllocL, the below steps will excute

1. creating a new heap descriptor.

2. copying the original data into the new descriptor.

3. deleting the original descriptor.

Br/Yin

Tue, 2007-09-18 04:16
Joined: 2007-09-17
Forum posts: 11
Re: There is a question about HBufC*

Evil
At mickyfirst --
i'm sorry ,still or error!
Did you debug in VC6.0 sp6 environment ?

HBufC* newBuffer = myHeapDes->ReAllocL(KString2().Length()); 
        CleanupStack::Pop(myHeapDes);
        CleanupStack::PushL(newBuffer);  //NOTICE: don't forget to call
        //CleanupStack::Pop(newBuffer) at appropiate line
       
        //Replace entire string in the HBufC
        *newBuffer = KString2;
        console->Printf(KFromat1,newBuffer,newBuffer->Length());
        CleanupStack::PopAndDestroy(newBuffer);

as your code ,BUT it is WRONG!
maybe it is the address of myHeapDes when it call ReAllocL() is changed ,rbrunner is correct,it return a correct address,and we need to store it!


i'm a student,you are my teacher.

Tue, 2007-09-18 19:44
Joined: 2006-05-09
Forum posts: 78
on the ReAlloc() memory allocation

You do need to pop HBufs off the cleanupstack and repush them.

Also the code in
http://descriptors.blogspot.com/2005/05/20-how-do-i-use-heap-based-buffer.html
is incorrect.

The following code will panic if the cell is moved:

HBufC* buf = .....
CleanupStack::PushL(buf);
buf = buf->ReAllocL(5000);
CleanupStack::PopAndDestroy(buf);

After the realloc it should be:
CleanupStack::Pop();
CleanupStack::PushL(buf);
.....
CleanupStack::PopAndDestory(buf);

Try it for yourself and see, you can try and force the call to ReAlloc() to move the memory by preceeding it with a call to something like
TUint* scrap = (TUint*) User::Alloc(5000);

If you want to understand descriptors read the chapter on them in
http://www.amazon.co.uk/Symbian-OS-Mobile-Phones-Press/dp/0470066415/ref=sr_1_1/203-1802158-8469513?ie=UTF8&s=books&qid=1190141073&sr=1-1

Wed, 2007-09-19 05:06
Joined: 2007-09-17
Forum posts: 11
Re: There is

Smiling
AT Fructose:
Thanks Very much.
That is right!
In your help, I have modified my code to ensure its accuracy!


i'm a student,you are my teacher.

Thu, 2007-09-20 06:32
Joined: 2007-04-29
Forum posts: 51
Re: There is a question about HBufC*

My tool is CodeWarrior 5.5.3.1604

Thu, 2007-09-20 07:20
Joined: 2007-07-25
Forum posts: 2
Re: There is a question about HBufC* on the ReAlloc() memory...

Hey guys, it is an interesting topic. ReAlloc is often misunderstood (and hence, misused).
@ huangfangcheng: Have you tried RBuf yet? RBufs are the most useful descriptors for these scenarios. Also, if all the HBufC*s do is hold literals, probably you can work with just TPtrC. But I presume that the code is just for illustration.

Fri, 2007-09-21 08:11
Joined: 2007-09-17
Forum posts: 11
Re: There is a question about

Hi all:

Yes ,I remember had a documentation file (.PDF) pressed by Symbian, specialized explain aboud RBuf.
RBuf derivatived dircted By TDes.But as I know ,Series 60 2nd SDK did't support RBuf.


i'm a student,you are my teacher.

Fri, 2007-09-21 10:14
Joined: 2004-05-21
Forum posts: 285
Re: There is a question about HBufC* on the ReAlloc()

Check out this pdf http://developer.symbian.com/main/downloads/papers/RBuf/Introduction_to_RBuf_v1.0.pdf. It says "RBuf descriptors were introduced in Symbian OS v9 and backported to v8.1 and v8.0"

Cheers,
Sri

Sat, 2007-09-22 03:45
Joined: 2007-09-17
Forum posts: 11
Re: There is a question

Smiling
Hah,
Right,

Cheers,
huang


i'm a student,you are my teacher.

  • Login to reply to this topic.