myHeapDes->ReAllocL(KString2().Length());
//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()
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
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.
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;
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!
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...
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());
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!
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);
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.
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.
Forum posts: 286
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
Forum posts: 61
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;
Forum posts: 11
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.
Forum posts: 1321
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
Forum posts: 11
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.
Forum posts: 61
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
Forum posts: 11
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.
Forum posts: 78
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
Forum posts: 11
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.
Forum posts: 61
My tool is CodeWarrior 5.5.3.1604
Forum posts: 2
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.
Forum posts: 11
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.
Forum posts: 286
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
Forum posts: 11
Hah,
Right,
Cheers,
huang
i'm a student,you are my teacher.