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
似乎可以解决问题。
我正在使用 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
似乎可以解决问题。