c++ - 在向量中使用 std::filesystem::path 时双重释放

c++ - double free when using std::filesystem::path in a vector

我正在使用 DearImgui 开发一个简单的文件浏览器。为此,我将 std::filesystem 与 g++-9 一起使用,目前正在 Kubuntu 19.04 上进行测试。在大多数情况下,该程序按预期工作。一个按钮用于进入父目录,双击它可以打开子目录。大多数时候我可以毫无问题地浏览整个文件系统,但是某些命令组合会导致程序中止。确切的错误消息各不相同,但始终与双重释放错误有关。

在将 std::filesystem 添加到我的应用程序之前,我使用的是 g++-8 (Ubuntu 8.3.0-6ubuntu1)。但是,该程序在调用与文件系统相关的内容后一直出现段错误。这似乎是一个已知问题,应在 8.3.0-7 (source) 中修复。与此同时,我决定使用 g++-9 (Ubuntu 9.1.0-2ubuntu2~19.04)。我不确定这是否是我的问题的原因。

这是导致中止的代码:

namespace fs = std::filesystem;
struct FileBrowser {

    fs::path currentPath = fs::current_path();
    std::vector<fs::path> files;

    void UpdateFiles() {
        files.clear();
        for (auto& entry : fs::directory_iterator(currentPath))
            files.push_back(entry.path()); // Leak_DefinitelyLost
    }

    void DrawContent() {
        if (BackButtonPressed && currentPath.has_parent()) {
            currentPath = currentPath.parent_path(); // Jump depends on uninitialised value
            UpdateFiles();
        }

        static bool invalidate = false;
        for (auto& entry : files) {
            if (ClickedOnThisEntry && fs::is_directory(entry)) {
                currentPath = entry; // InvalidRead
                invalidate = true;
            }
        }
        if (invalidate) {
            UpdateFiles();
            invalidate = true;
        }
    }

};

当 运行使用 Valgrind 连接程序时,它会在更新路径向量和未初始化条件时报告泄漏。 主要错误似乎是尝试将所选路径复制到当前路径时出现无效读取。

可重现的示例需要 SDL2 和 imgui。如果有人感兴趣,我可以 post 一个。

有趣的是,当我 运行 gdb 中的程序并触发中止时,我无法再使用鼠标点击任何东西(即使是不相关的应用程序,如 firefox)。我仍然可以使用键盘并通过命令行终止 gdb。在这个项目中以前没有发生过类似的事情,我无法在程序的不相关部分重现它。这可能是由 Imgui 引​​起的,但我对此表示怀疑。

我找到了问题的解决方案。使用 assign(...) 函数而不是赋值运算符 = 更新 currentPath 似乎可以解决问题。