C++ - двойное освобождение при использовании std::filesystem::path в векторе

Я работаю над файловым браузером с использованием 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 через командную строку. Нечто подобное еще не случалось в этом проекте, и я не могу воспроизвести это в какой-то другой части программы. Это могло быть вызвано Imgui, но я сомневаюсь в этом.

1 ответ

Решение

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

Другие вопросы по тегам