Reputation: 4557
I'm working on an existing data parsing program that overlays a struct onto a buffer in order to extract values. Recently a new data format has been added to the buffer and requires a new struct. I abstracted functions into a common base class and defined a new struct like this:
struct Header
{
Header () { }
public:
virtual unsigned __int8 getCommonField1() const = 0;
}
struct HeaderTypeA : public Header
{
unsigned __int8 Field1;
public:
unsigned __int8 getCommonField1() const { return Field1; }
}
struct HeaderTypeB : public Header
{
unsigned __int8 Field0;
unsigned __int8 Field1;
public:
unsigned __int8 getCommonField1() const { return Field1; }
}
The existing code which does the processing evaluates the data (this is working) and returns a pointer to the calling function... something like this:
Header* parse()
{
Header* parsedHeader = 0;
if (typeADetected)
{
parsedHeader = (HeaderTypeA *) &buffer[offset];
// Other logic here...
}
else if (typeBDetected)
{
parsedHeader = (HeaderTypeB *) &buffer[offset];
// Other logic here...
}
return (parsedHeader);
}
The problem arises in the caller of the parsing logic. When the header is returned as a pointer the calls to the member functions result in an access violation error:
Header * hdr;
hdr = m_parser->parse();
unsigned __int8 value = hdr->getCommonField1(); // Access Violation
I realize the snippet above is missing null pointer checks; I have excluded some of that logic for brevity. I've traced the code through and everything appears to be running smoothly until an attempt is made to call a method on the base class. In playing around with the code, I've also seen member function not present errors.
Thanks for any help.
Upvotes: 3
Views: 913
Reputation: 114795
You seem to be using the memory in buffer
without constructing an object there. Since Header
is polymorphic it contains a virtual table pointer and you can't initialize its data directly (legally you can't even if it's a POD but you would probably get away with it).
You should be using placement new
in order to construct the Header
object in buffer
.
parsedHeader = new (&buffer[offset]) HeaderTypeA;
Upvotes: 5