i am passing HBuf to function
but it crashes i don't know whether i am following right way or not
//case 1:
HBufC8* iBuffer2 = HBufC8::NewL(1000 );
TPtr8 bufferPtr( iBuffer2->Des() );
//assigning value to HBuf code
StartParsingL(iBuffer2);
StartParsingL(HBufC8* aHBufPtr)
{
iBuffer = HBufC8::NewL(aHBufPtr->Length());//it crashes here
bufferPtr.Copy(aHBufPtr->Des());//also here
}
Not answering your question (as there isn't really enough information). I would recommend using an RBuf instead of a HBuf as they are the recommended heap buffer descriptor going forward, and a bit easier to use.
In the Symbian coding convention, "i" prefixed variables are member variables.
In your snippet you have it as a local declaration. It could be that you just put in the type for clarity of the snippet, but if you've declared it both as a member variable and as a local declaration, that could explain plenty of crashes :-)
You should have:
class C....: public CBase?....
{
private:
HBufC8* iBuffer2;
};
...
void C...::ConstructL()
{
...
iBuffer2 = HBufC8::NewL(1000);
...
}
This code does not directly show the reason for crashing. Please post actual snippets next time.
Also, when posting about a crash, it is good to know how it is crashing. I assume it is a KERN-EXEC 3 panic. But please be explicit about it yourself.
I guess the aHBufPtr passed to StartParsingL is either zero or otherwise does not point to a valid HBuf8 object. That would be the immediate reason for the crash. Why it is not a valid pointer is not visible in the code, but one reason could be shadowing a member variable with a local variable as suspected by #Will.
Some further points, not related to crash here but Symbian C++ in general:
When passing descriptors around, you should use the most general read-only TDesC or TDesC8 type references or read-write TDes or TDes8 type references. Use HBufC or HBufC8 pointers only if you are transferring ownership to the callee.
In this snippet:
bufferPtr.Copy(aHBufPtr->Des());
Copy accepts a TDesC& so you do not need to call Des:
bufferPtr.Copy(*aHBufPtr);
Though if you just want to copy a descriptor, you could use any of the descriptor Alloc functions such as AllocL.
Related
I made the following method in a C++/CLI project:
void GetSessionData(CDROM_TOC_SESSION_DATA& data)
{
auto state = CDROM_TOC_SESSION_DATA{};
// ...
data = state;
}
Then I use it like this in another method:
CDROM_TOC_SESSION_DATA data;
GetSessionData(data);
// do something with data
It does work, returned data is not garbage, however there's something I don't understand.
Question:
C++ is supposed to clean up state when it has exitted its scope, so data is a copy of state, correct ?
And in what exactly it is different from the following you see on many examples:
CDROM_TOC_SESSION_DATA data;
GetSessionData(&data); // signature should be GetSession(CDROM_TOC_SESSION_DATA *data)
Which one makes more sense to use or is the right way ?
Reference:
CDROM_TOC_SESSION_DATA
Using a reference vs a pointer for an out parameter is really more of a matter of style. Both function equally well, but some people feel that the explicit & when calling a function makes it more clear that the function may modify the parameter it was passed.
i.e.
doAThing(someObject);
// It's not clear that doAThing accepts a reference and
// therefore may modify someObject
vs
doAThing(&someObject);
// It's clear that doAThing accepts a pointer and it's
// therefore possible for it to modify someOjbect
Note that 99% of the time the correct way to return a class/struct type is to just return it. i.e.:
MyType getObject()
{
MyType object{};
// ...
return object;
}
Called as
auto obj = getObject();
In the specific case of CDROM_TOC_SESSION_DATA it likely makes sense to use an out parameter, since the class contains a flexible array member. That means that the parameter is almost certainly a reference/pointer to the beginning of some memory buffer that's larger than sizeof(CDROM_TOC_SESSION_DATA), and so must be handled in a somewhat peculiar way.
C++ is supposed to clean up state when it has exitted its scope, so
data is a copy of state, correct ?
In the first example, the statement
data = state
presumably copies the value of state into local variable data, which is a reference to the same object that is identified by data in the caller's scope (because those are the chosen names -- they don't have to match). I say "presumably" because in principle, an overridden assignment operator could do something else entirely. In any library you would actually want to use, you can assume that the assignment operator does something sensible, but it may be important to know the details, so you should check.
The lifetimes of local variables data and state end when the method exits. They will be cleaned up at that point, and no attempt may be made to access them thereafter. None of that affects the caller's data object.
And in what exactly it is different from the following you see on many
examples:
CDROM_TOC_SESSION_DATA data;
GetSessionData(&data);
Not much. Here the caller passes a pointer instead of a reference. GetSessionData must be declared appropriately for that, and its implementation must explicitly dereference the pointer to access the caller's data object, but the general idea is the same for most intents and purposes. Pointer and reference are similar mechanisms for indirect access.
Which one makes more sense to use or is the right way ?
It depends. Passing a reference is generally a bit more idiomatic in C++, and it has the advantage that the method does not have to worry about receiving a null or invalid pointer. On the other hand, passing a pointer is necessary if the function has C linkage, or if you need to accommodate the possibility of receiving a null pointer.
I'm getting to grips with references in C++ and I have a small query surrounding references & scoping, for this it's probably best to create an example:
Imagine I have a method in "BankDatabase.cpp" which takes a bank record by reference and adds it to a data structure (also by reference).
void AddRecord( BankRecord& bankRecord )
{
//Add record to data structure by reference
}
If I run a method like so:
void TestAddRecord( BankDatabase& bankDatabase )
{
BankRecord bankRecord { "John", "Doe", 9999 }
bankDatabase.AddRecord( bankRecord );
}
To my mind, "bankRecord" falls out of scope (as do its two strings and int) and is thus cleared from memory at the end of the "TestAddRecord" method, leaving "bankDatabase" pointing at some empty memory?
If so what's the general accepted standard / resolution to such a scenario? It seems a little mad to have to pass things by value...
In that case passing by value seems like the way to go. Allocating a new BankRecord pointer will work too. Storing things by reference is not very great.
However if I'm not mistaking, your two strings and the int won't be lost since they are present in the stack and will not be deallocated. But bankRecord will still be lost.
The best way to answer these concerns is to step through the code in the debugger and see what the Vector is doing with the variable being appended. Look especially at the constructor calls as you step into the data structure's Append functions. Because I do not know your underlying data structure, it is a bit more difficult for me to tell you more information. I will assume it is a std::vector for now until told otherwise.
You may be surprised to learn that references passed through a function do not tell the entire story about when it will go in and out of scope. I often think of C++ references as pointers that do not need nullptr checks.
Your code will work fine as long as the reference is copied into the vector or does not go out of scope because the variable it pointed to was destroyed. The reference will not go out of scope if it is referring to a member variable or memory on the heap for your particular case.
If the reference was declared on the stack to a variable created on the stack, and then appended to the vector, then you will have scope problems.
You should also look into emplace() if you have C++11 and the compiler supports move semantics.
In short, the most important thing you can do here is step through the code and see what Constructors are being called. This will give you the answer you desire.
I have a situation in which I have an object of type Foo, in which calling its own methods somehow loses track of its own address in "this". I have defined these functions:
// Bar has an instance of foo, and wishes to call a function001()...
Bar::doThingWithFoo(){
// foo is at address 0x1a7bbb70 here...
foo->function001();
}
// The definition of function001(). The address of "this" is as expected.
Foo::function001(){
// the address of "this" is 0x1a7bbb70 here...
this->function002();
}
Foo::function002(){
// but the address of "this" is 0xbfffe090 here!!!
// bad things happen, as you might expect.
this->getMyProperty()->doThing();
}
Why might something like this happen?
Perhaps you are using multiple inheritance, which causes the pointer value of this to be context-dependent:
http://frogchunk.com/documentation/lang/cpp/Multiple_inheritance_and_the_this_pointer.pdf
That causes problems if you use C casts instead of dynamic_cast.
I agree with the comments that we need to see the actual code. I will speculate that 0xbfffe090 looks like an address on the stack which means you may have accidentally copied your object and then invoked a method on the copy. It would also be consistent with some kind of memory corruption (overwriting a local array, for example) with some local address.
Wild speculative guess would be what others have also eluded to that you might be having some sort of buffer over-flow case at other place in your code where the buffer overflow is corrupting this.
It would help to know the code.
I would imagine if its a memory corruption it would cause it have a core dump, did you notice one ?
Answering my own question : alltom's answer was actually closer than it might seem, but ultimately it was of course memory corruption. Memory became corrupted inside function001 prior to function002 being called because of an object being used as a delegate. The delegate had been passed and stored as a void*, and C-style cast back into its object type to call its relevant methods.
The issue was resolved by storing the delegate object in a variable (eg: MyDelegate* delegate) rather than storing as void* and casting.
I've came across the following code, ok, not exactly but close.
The point of interest is the second line in the (heavily abbreviated code).
Why does one have to intialize someReference 'someReference' ? Other then be able to use . operator instead of -> ?
ptrThis is just as good, no? (it's inside the thread method, if that makes any difference)
// this line, why?
SomeClass & someReference(*ptrThis);
unsigned SomeClass::someThread(void *ptr)
{
SomeClass *ptrThis = reinterpret_cast<SomeClass*>(ptr);
SomeClass & someReference(*ptrThis);
// some other code
}
References always need to be initialized when they're declared (unless they're external). They remain bound to one object during their whole lifetime. This ensures that a reference, unlike a normal pointer, can (theoretically) never be NULL because it must refer to somebody. Assigning to a reference assigns to the referencee.
Yes; ptrThis is just as good. Matter of style, I suppose. It does seem a bit redundant given what you've posted, but I'll give the original author the benefit of the doubt that it made sense in the context of the full example.
It doesn't have to do anything related to threads and as such cant interpret much from what code snippet which you have given
My program is crashing every time I try to store a COM pointer into a struct, and then later try to use the original pointer. I don't have debug access to tell exactly what's wrong.
pRend->cp = cpRT;
ID2D1SolidColorBrush *scBrush;
ERF(cpRT->CreateSolidColorBrush(D2D1::ColorF(D2D1::ColorF::CornflowerBlue), &scBrush));
It crashes on CreateSolidColorBrush. However, if I comment out pRend->cp = cpRT, it doesn't.
By the way, pRend->cp and cpRT are of type ID2D1HwndRenderTarget *.
Instead of assigning directly QI and then store i.e.,
pRend->cp = cpRT;
should be replaced with
cpRT->QueryInterface(&pRend->cp);
It's unclear how much code exists between when you assign it into the struct and later use it in CreateSolidColorBrush. If it's a non-trivial amount of time, it's possible that you have a reference counting issue.
Are you storing a raw pointer in the struct? If so, switch it to a CComPtr and see if the crash goes away.
For instance. If you had the following type definition for the value of pRend (call it Render) and the value pRend was destroyed before making the CreateSolidColorBrush call, you could see this behavior.
struct Render {
ID2D1HwndRenderTarget *pCt;
~Render() {
pCt->Release();
}
};
As it turns out, I managed to stop the crashing by allocating pRend with malloc. This is not a problem because I will call free when I don't need it anymore. I'm interested in why calling malloc fixes this though. I'm used to just doing Datatype * var; and then just using var. Is that bad?
It's a smart pointer. I'm guessing you're inadvertantly calling release on it. In particular, it's addressof operator (unary op&) is overriden to call Release().
See what happens if you instead assign it to a reference, an ID2D1HwndRenderTarget*&.
Obviously, if you assign to a reference, you won't be able to reseat it.