bporter
bporter

Reputation: 4557

C++ Access Violation

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

Answers (1)

Motti
Motti

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

Related Questions