std :: sort中的错误?

Eva*_*ran 1 c++ sorting vector segmentation-fault c++11

好吧,我通常默认假设错误在我的代码中,但我所看到的对我来说几乎没有意义.


我有一个std::vector<DocumentWidget *>,我希望通过一些相对简单的算法进行排序.这就是我所看到的.

代码如下所示:

std::vector<DocumentWidget *> documents = DocumentWidget::allDocuments();

// NOTE(eteran): on my system, I have observed a **consistent** crash
// when documents.size() == 17 while using std::sort.
std::sort(documents.begin(), documents.end(), [](const DocumentWidget *a, const DocumentWidget *b) {

    int rc = (a->filenameSet_ == b->filenameSet_) ? 0 : a->filenameSet_ && !b->filenameSet_ ? 1 : -1;
    if (rc != 0) {
        return rc < 0;
    }
    if(a->filename_ < b->filename_) {
        return true;
    }
    return a->path_ < b->path_;
});
Run Code Online (Sandbox Code Playgroud)

看起来很简单,但是当我在列表中有第17个项目时它会崩溃!排序谓词显然没有vector以任何方式修改,所以我看不出这是一个问题.地址清理器和valgrind在此之前没有显示任何错误.

qSort 不崩溃,似乎工作正常.正在运行的任何其他线程都在触摸这个数据,和它发生可靠无论我怎么慢慢地一步...所以它不是一个竞争状态.

当我查看调试器时,a参数似乎是"一个结束"迭代器所指向的位置.但如果std::sort行为不应该发生这种情况紧急.

注意有17项std::vector,我强迫调试器显示第18项,以说明a似乎来自哪里.

我无法想象这std::sort是错误的,但我真的很难找到另一种解释.我在这里错过了一些明显的错误吗?!

T.C*_*.C. 15

if(a->filename_ < b->filename_) {
    return true;
}
return a->path_ < b->path_;
Run Code Online (Sandbox Code Playgroud)

这被称为"不是有效的严格弱序":

{ "a", "d" } < { "b", "c"}; because "a" < "b"
{ "b", "c" } < { "a", "d"}; because "c" < "d"
Run Code Online (Sandbox Code Playgroud)

修复很简单:不要重新发明轮子:

return std::tie(a->filename_, a->path_) < std::tie(b->filename_, b->path_);
Run Code Online (Sandbox Code Playgroud)