简体   繁体   English

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

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

I'm working on a bare-bones file browser using DearImgui . 我正在使用DearImgui在准文件浏览器上工作 For this i'm using std::filesystem with g++-9 and am currently testing on Kubuntu 19.04. 为此,我使用带有g ++-9的std :: filesystem,目前正在Kubuntu 19.04上进行测试。 For the most part the program works as expected. 在大多数情况下,程序可以按预期运行。 A button is used to descend into the parent directory and a child directory can be opened by double clicking on it. 使用一个按钮可以下降到父目录,然后双击可以打开一个子目录。 Most of the time i can navigate through the entire filesystem without issues, however certain combinations of commands cause the program to abort. 大多数时候,我可以无问题地浏览整个文件系统,但是某些命令组合会导致程序中止。 The exact error message varies but is always related to a double free error. 确切的错误消息有所不同,但始终与双重释放错误有关。

Before adding std::filesystem to my application i was using g++-8 (Ubuntu 8.3.0-6ubuntu1). 在将std :: filesystem添加到我的应用程序之前,我使用的是g ++-8(Ubuntu 8.3.0-6ubuntu1)。 However the program kept segfaulting after calling something filesystem related. 但是,该程序在调用与文件系统相关的某些内容后仍然存在段错误。 This appears to be a known issue and should be fixed with 8.3.0-7 (source) . 这似乎是一个已知问题,应使用8.3.0-7修复(源) In the meantime i decided to use g++-9 (Ubuntu 9.1.0-2ubuntu2~19.04). 同时,我决定使用g ++-9(Ubuntu 9.1.0-2ubuntu2〜19.04)。 I am not sure if this might be the cause of my problem. 我不确定这是否是造成我问题的原因。

Here is the code that causes the abort: 这是导致中止的代码:

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

};

When running the program with Valgrind it reports a leak when updating the path vector and an uninitialised condition. 使用Valgrind运行程序时,它会在更新路径向量和未初始化的条件时报告泄漏。 The main error seems to be the Invalid Read when trying to copy the selected path into the current path. 尝试将所选路径复制到当前路径时,主要错误似乎是无效读取。

A reproducable example would require SDL2 and imgui. 一个可重现的示例将需要SDL2和imgui。 I can post one if somebody is interested. 如果有人感兴趣,我可以发布一个。

What's interesting is that when i run the program in gdb and trigger an abort i can no longer use my mouse to click on anything (even unrelated applications like firefox). 有趣的是,当我在gdb中运行该程序并触发中止操作时,我无法再使用鼠标单击任何东西(即使是不相关的应用程序,例如firefox)。 I can still use the keyboard and kill gdb through the command line. 我仍然可以使用键盘并通过命令行杀死gdb。 Something like that has not happened before in this project and i can't reproduce it in an unrelated part of the program. 在该项目中以前从未发生过类似的事情,我无法在程序的无关部分中重现它。 This could be caused by Imgui but i doubt it. 这可能是由Imgui引起的,但我对此表示怀疑。

I found a solution for the problem. 我找到了解决问题的办法。 Updating currentPath with the assign(...) function instead of the assignment operator = seems to fix the problem. 使用assign(...)函数而不是赋值运算符=更新currentPath似乎可以解决此问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM