簡體   English   中英

對文件系統路徑向量進行排序時,“嘗試取消引用過去的迭代器”

[英]'Attempt to dereference a past-the-end iterator' when sorting a vector of filesystem paths

我正在使用std :: filesystem編寫一個簡單的文件選擇器。 當前目錄的條目存儲在向量中。 當我嘗試使用std :: sort對向量進行排序時,程序崩潰。

在Ubuntu 19.04上使用g ++-9會發生這種情況。 使用-D_GLIBCXX_DEBUG和-D_GLIBCXX_DEBUG_PEDANTIC調試標志編譯該文件。

相關代碼如下:

#include <filesystem>
#include <vector>
#include <algorithm>

namespace fs = std::filesystem;

struct FileBrowser {
    std::vector<fs::path> files;

    FileBrowser() {
        UpdateFiles();
    }

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


        std::sort(files.begin(), files.end(), [](const auto& lhs, const auto& rhs) {
            if (fs::is_directory(lhs) && !fs::is_directory(rhs)) {
                return 1;
            } else if (fs::is_directory(rhs) && !fs::is_directory(lhs)) {
                return 0;
            } else {
                return lhs.filename().string().compare(rhs.filename().string());
            }
        });
    }
};

錯誤消息如下所示:

/usr/include/c++/9/debug/safe_iterator.h:294:
In function:
    __gnu_debug::_Safe_iterator<_Iterator, _Sequence, _Category>::reference 
    __gnu_debug::_Safe_iterator<_Iterator, _Sequence, 
    _Category>::operator*() const [with _Iterator = 
    __gnu_cxx::__normal_iterator<std::filesystem::__cxx11::path*, 
    std::__cxx1998::vector<std::filesystem::__cxx11::path, 
    std::allocator<std::filesystem::__cxx11::path> > >; _Sequence = 
    std::__debug::vector<std::filesystem::__cxx11::path>; _Category = 
    std::forward_iterator_tag; __gnu_debug::_Safe_iterator<_Iterator, 
    _Sequence, _Category>::reference = std::filesystem::__cxx11::path&]

Error: attempt to dereference a past-the-end iterator.

Objects involved in the operation:
    iterator "this" @ 0x0x7fff6c67d9d0 {
      type = __gnu_cxx::__normal_iterator<std::filesystem::__cxx11::path*, std::__cxx1998::vector<std::filesystem::__cxx11::path, std::allocator<std::filesystem::__cxx11::path> > > (mutable iterator);
      state = past-the-end;
      references sequence with type 'std::__debug::vector<std::filesystem::__cxx11::path, std::allocator<std::filesystem::__cxx11::path> >' @ 0x0x55ca5b4536c0
    }

我在網上看到很多例子,其中使用vector.end()調用std :: sort。 我嘗試使用files.end() - 1並收到了相同的錯誤消息。

std::sort需要嚴格的弱排序比較器,如[alg.sorting] / p3中所述

對於除[alg.binary.search]中所述的算法以外的其他算法, comp應在值上引入嚴格的弱排序。

僅當左側操作數在右側操作數之前時,嚴格的弱排序比較器才應返回true否則返回false

所述std::basic_string::compare函數編碼其結果作為<0 0>0 ,如果字符串分別按字典順序小於,等於或大於參數表達式。 這樣可以一次確定其參數之間的相互關系。 但是,正值和負值都可以隱式轉換為true布爾值,因此任何標准庫算法都將錯誤地解釋結果,從而導致不確定的行為。 為了避免這種情況, std::sort函數調用可能如下所示:

std::sort(files.begin(), files.end(), [](const auto& lhs, const auto& rhs) {
    if (fs::is_directory(lhs) && !fs::is_directory(rhs)) {
        return true;
    } else if (fs::is_directory(rhs) && !fs::is_directory(lhs)) {
        return false;
    } else {
        return lhs.filename().string() < rhs.filename().string();
        //                            ~^~
    }
});

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM