我有撤消/重做时释放内存时的问题

时间:2014-12-09 05:21:08

标签: c++ vector memory-leaks valgrind

我正在为一个类的项目工作,我们应该为文本编辑器实现基本功能,包括undo和redo。我目前正在使用我的undo / redo函数正常工作,唯一的问题是,当我试图从Command对象释放内存时,我得到了一个valgrind错误,该对象告诉我们要执行什么。

这个Command对象是名称空间中结构的一部分,如下所示:

struct UserInteraction
{
    UserInteractionType type;
    Command* command;
};

目前,我将用户发出的每个命令存储在名为<UserInteraction>的{​​{1}}类型的std :: vector中。我也有一个相同类型的undoStack,它也是一个std :: vector。存储每个命令如下所示:

redoStack

当用户按下ctrl + x(退出程序)时,我需要解除分配到向量中的每个UserInteraction。否则,我发出的任何命令都会给我一个错误:

else if (interaction.type == UserInteractionType::command) // COMMAND { try { interaction.command->execute(editor); commandInteraction = true; undoStack.push_back(interaction); view.clearErrorMessage(); } catch (EditorException& e) { delete interaction.command; view.showErrorMessage(e.getReason()); } view.refresh(); } // end if-else

输入的每个命令都会使丢失的字节数增加4。

我想我只需要在quit命令中释放每个向量所使用的所有内存,但人们使用的所有当前解决方案似乎仍然给我内存泄漏。以下是我的退出方法的两个版本(这两个版本仍然给我内存泄漏):

首先尝试:

4 bytes in 1 blocks are definitely lost in loss record 2 of 38

我第二次尝试释放内存:

    if (interaction.type == UserInteractionType::quit)
    {
        clear undo
        std::vector<UserInteraction>().swap(undoStack);
        clear redo
        std::vector<UserInteraction>().swap(redoStack);
        break;
    }

那么我怎样才能真正解除两个向量中的所有内容呢?

1 个答案:

答案 0 :(得分:1)

通过释放向量的内存,您只会破坏UserInteractions,但不会破坏它们指向的命令。如果使用c ++ 11编译器,则可以使用智能指针。

struct UserInteraction
{
    UserInteractionType type;
    std::unique_ptr<Command> command;
    // or
    std::shared_ptr<Command> command;
};

这将自动处理删除命令。如果没有,我只是删除迭代遍历向量元素的循环中的所有命令。 (您还可以编写一个删除命令的costum析构函数,以及一个复制赋值运算符和-ctor(深层复制),以及移动赋值运算符和-ctor,但这似乎是一个过于复杂的解决方案)