Нарушение доступа C ++ - PullRequest
       2

Нарушение доступа C ++

3 голосов
/ 01 сентября 2011

Я работаю над существующей программой синтаксического анализа данных, которая накладывает структуру на буфер для извлечения значений. Недавно новый формат данных был добавлен в буфер и требует новой структуры. Я абстрагировал функции в общий базовый класс и определил новую структуру следующим образом:

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; }
}

Существующий код, который выполняет обработку, оценивает данные (это работает) и возвращает указатель на вызывающую функцию ... примерно так:

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);
}

Проблема возникает в вызывающей логике синтаксического анализа. Когда заголовок возвращается как указатель, вызовы функций-членов приводят к ошибке нарушения доступа:

Header * hdr;
hdr = m_parser->parse();
unsigned __int8 value = hdr->getCommonField1(); // Access Violation

Я понимаю, что во фрагменте выше отсутствуют проверки нулевого указателя; Я исключил некоторые из этой логики для краткости. Я проследил код до конца, и все, кажется, работает гладко, пока не будет предпринята попытка вызвать метод базового класса. Играя с кодом, я также видел функция-член отсутствует ошибки.

Спасибо за любую помощь.

1 Ответ

5 голосов
/ 01 сентября 2011

Вы, кажется, используете память в buffer, не создавая там объект.Поскольку Header является полиморфным, он содержит указатель виртуальной таблицы, и вы не можете инициализировать его данные напрямую (юридически вы не можете, даже если это POD , но вам, вероятно, это сойдет с рук).

Для построения объекта Header в buffer.

 parsedHeader = new (&buffer[offset]) HeaderTypeA;
вы должны использовать размещение new.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...