Consider the following simplified code:
typedef struct __attribute__ ((__packed__)) {
int numberB;
std::string strA;
} StructA;
typedef struct __attribute__ ((__packed__)) {
int numberB;
std::string strB;
} StructB;
char *ExampleClass::getBuffer(void){
char* mBuf;
int offset = 10;
return mBuf offset;
}
void ExampleClass::ExampleFunction(StructA *A){
StructB *B = (StructB *)getBuffer();
B->numberB = A->numberA;
B->strB = A->strA;
return;
}
There is a lot of code not shown here intentionally, but I believe the root of my question do be demonstrated: Why do I get a segmentation fault when trying to assign B->strB = A->strA?
Thanks
CodePudding user response:
In getBuffer(), mBuf is uninitialized, but you add offset to it, so the pointer being return'ed is indeterminate. It certainly does not point at a valid StructB object, which is why the subsequent code in ExampleFunction() crashes when accessing B's members. Technically, this is undefined behavior, so anything can happen, a crash is not guaranteed.
But, even if mBuf were initialized to a valid char[] buffer large enough to hold a StructB object, there is still no StructB object actually being constructed in this code, thus B->numberB and B->strA are not valid objects.
getBuffer() would need to do something more like this:
char* ExampleClass::getBuffer(){
char* mBuf = ...; // point to some char[] buffer that is at
// least 10 sizeof(StructB) in size, and
// isn't deallocated when getBuffer exits...
int offset = 10;
new(mBuf offset) StructB;
return mBuf offset;
}
void ExampleClass::ExampleFunction(StructA *A){
StructB *B = (StructB *)getBuffer();
B->numberB = A->numberA;
B->strB = A->strA;
B->~StructB();
}
Or else, ExampleFunction() would need to do this instead:
char* ExampleClass::getBuffer(){
char* mBuf = ...; // point to some char[] buffer that is at
// least 10 sizeof(StructB) in size, and
// isn't deallocated when getBuffer exits...
int offset = 10;
return mBuf offset;
}
void ExampleClass::ExampleFunction(StructA *A){
StructB *B = new(getBuffer()) StructB;
B->numberB = A->numberA;
B->strB = A->strA;
B->~StructB();
}
