Ошибка сегментации при вызове метода по указателю базового класса

#c #segmentation-fault #polymorphism #virtual-functions

#c #ошибка сегментации #полиморфизм #виртуальные функции

Вопрос:

Я пытаюсь создать FSM для простого компилятора.
Я решил создать массив фиксированного размера с интерфейсными указателями на состояния. Эта концепция оказалась успешной с простым заполнителем FSM, который читает HTML.
Однако реальный FSM не будет работать: я получаю ошибку сегментации (при 0x0) при вызове метода обработки состояний.

Вот создание экземпляра:

 this->states[0] = new State0();
this->states[1] = new State1();
this->states[2] = new State2();
this->states[3] = new State3();
this->states[4] = new State4();
[...]
  

Когда я прохожу через это, я вижу, что соответствующий адрес меняется после каждого назначения.

Массив определяется таким образом:

 #define STATE_COUNT 17
[...]
IState * states[STATE_COUNT];
  

IState:

 class IState {
public:
    virtual ~IState() {};
    virtual int getNextState(char) = 0;
    virtual bool isFinal() = 0;
    virtual TokenType getTokenType() = 0;
};
  

State0, с минимизированным кодом для целей тестирования:

 class State0 : public IState
{
public:
    virtual ~State0();
    int getNextState(char c)
    {
        return 0;
    }

    bool isFinal()
    {
        return this->final;
    }

    TokenType getTokenType()
    {
        return this->tokenType;
    }
private:
    TokenType tokenType;
    bool final;
};
  

Теперь следующая строка кода вызывает ошибку SEGFAULT:

 this->nextState = this->states[currentState]->getNextState(c);
  

currentState равно 0, поскольку это происходит при самом первом вызове.

Итак, я думаю, что это не проблема области видимости и не нулевой указатель. За исключением, возможно, нулевого значения этого указателя в объектах состояния?

Комментарии:

1. Вы действительно уверены currentState 0 , что это так? Вы распечатали его перед вызовом?

2. Я прошел, так что да. Но тем временем я определил проблему — я забыл переключить включенный заголовок при переключении объектных файлов. D:

3. К сожалению, очень распространенная ошибка, даже среди опытных программистов, я могу вас заверить!

4. Дэниел, добро пожаловать в Stack Overflow. Если вопрос может представлять ценность для других, пожалуйста, отправьте ответ в разделе ответов. Публикация ответа в теле вопроса — ужасная практика, она приведет к тому, что вы проголосуете против. Если это никому не нужно, удалите его. Но будьте осторожны… слишком много удалений, и вы будете забанены.

Ответ №1:

Как упоминалось в комментариях, эта проблема возникла из-за моей собственной небрежности. Я отредактировал свой Makefile для создания других объектов, но не смог изменить заголовки на новые в моем коде. Поэтому я связал («внешне» похожие) новые объектные файлы с другим кодом, все еще используя старые заголовки.