c ++ - двойное освобождение при использовании std :: filesystem :: path в векторе - PullRequest
2 голосов
/ 26 июня 2019

Я работаю в файловом браузере, используя DearImgui .Для этого я использую std :: filesystem с g ++ - 9 и сейчас тестирую на Kubuntu 19.04.По большей части программа работает как положено.Кнопка используется для перехода в родительский каталог, а дочерний каталог можно открыть, дважды щелкнув по нему.Большую часть времени я могу без проблем перемещаться по всей файловой системе, однако определенные комбинации команд приводят к прерыванию работы программы.Точное сообщение об ошибке варьируется, но всегда связано с ошибкой двойного освобождения.

Перед добавлением std :: filesystem в мое приложение я использовал g ++ - 8 (Ubuntu 8.3.0-6ubuntu1).Однако программа продолжала сегрегировать после вызова чего-то, связанного с файловой системой.Это, кажется, известная проблема и должна быть исправлена ​​с 8.3.0-7 (источник) .Тем временем я решил использовать 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.Я могу опубликовать его, если кому-то интересно.

Интересно то, что когда я запускаю программу в gdb и запускаю прерывание, я больше не могу использовать мышь, чтобы нажимать на что-либо (даже на не связанные приложения, такие как firefox).Я все еще могу использовать клавиатуру и убить GDB через командную строку.Нечто подобное еще не случалось в этом проекте, и я не могу воспроизвести это в какой-то другой части программы.Это могло быть вызвано Имгуи, но я сомневаюсь в этом.

1 Ответ

0 голосов
/ 28 июня 2019

Я нашел решение проблемы. Обновление currentPath с помощью функции assign(...) вместо оператора присваивания =, кажется, решает проблему.

...