将堆栈顶部存储到结构中时出现分段错误

时间:2014-12-07 11:51:37

标签: c++ segmentation-fault undo undo-redo command-pattern

我试图在一个超级简单的文本编辑器中实现一个撤消/重做功能,作为一个项目。我有一个类CommandProcessor,它接受​​用户按下的按钮,如果匹配,则执行一个泛型命令,该命令调用使用该特定命令的对象类型的execute()函数,即

struct UserInteraction
{
    UserInteractionType type; // this is just a enum type
    Command* command;
};

case 'U':
    command = new MoveLeft;
    return makeCommandInteraction(command);

这是它调用的MoveLeft命令:

void MoveLeft::execute(Editor& editor)
{
    // if we try to move past the amount of input, throw exception
    if(editor.cursorColumn() == 1) {
        throw EditorException("Already at beginning!");
    } else { // otherwise, move the cursor left
        editor.moveCursorLeft();
    }
}

在其中,这是被调用的编辑器命令。

void Editor::moveCursorLeft()
{
    column--;
}

如果用户点击ctrl + z或ctrl + a,我们会返回撤消/重做命令:return makeUndoInteraction();return makeRedoInteraction();

我使用两个堆栈,一个用于撤消,一个用于重做。 undoStack存储最新的命令,当在处理器中调用时,从MoveLeft调用撤销功能(当前只是向右移动光标),将undoStack的顶部推送到redoStack,然后弹出undoStack的顶部。 redoStack保存最后一个撤消命令,因此,我将其存储在interaction中,这是保存命令的类型。有了这个,我从MoveLeft调用execute(),然后将交互推回到undoStack这两个函数都是:

 else if (interaction.type == UserInteractionType::undo)
        {
            try
            {
                interaction.command->undo(editor);
                redoStack.push(undoStack.top());
                undoStack.pop();
                view.clearErrorMessage();
            } catch (EditorException& e)
            {
                view.showErrorMessage(e.getReason());
            }
            view.refresh();
            delete interaction.command; // delete command since we stored it in the stack
        }
        else if (interaction.type == UserInteractionType::redo)
        {
            try
            {
                interaction = redoStack.top();
                interaction.command->execute(editor);
                undoStack.push(interaction);
                view.clearErrorMessage();
            }
            catch (EditorException& e)
            {
                view.showErrorMessage(e.getReason());
            }
            view.refresh();
        }

现在我得到"分段错误(核心转储)"在撤消的这一行:

  

interaction.command->撤消(编辑);

如果我只是测试重做,我会在这一行得到一个分段错误:

  

interaction = redoStack.top();

两者都是try语句之后的第一行。可能导致什么呢?

0 个答案:

没有答案