好吧,我通常默认假设错误出在我的代码中,但我所看到的对我来说毫无意义。
我有一个 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_;
});
看起来很简单,但是当我在列表中有第 17 个项目时它会崩溃!排序谓词显然没有修改 vector
无论如何,所以我不认为这是一个问题。 Address sanitizer 和 valgrind 在此之前没有显示任何错误。
qSort
不会崩溃,似乎工作正常。没有其他正在运行的线程正在触及此数据,无论我的步调有多慢,它都会可靠地发生...所以这不是竞争条件。
当我查看调试器时,a
参数似乎是“最后一个”迭代器指向的地方。但是,如果 std::sort
,那不应该发生。正在表现 .
注意 std::vector
中有17项,我强制调试器显示第 18 项以说明 a
在哪里似乎来自。
我无法想象 std::sort
被窃听了,但我真的很难找到另一种解释。我在这里遗漏了一些明显的错误吗?!
最佳答案
if(a->filename_ < b->filename_) {
return true;
}
return a->path_ < b->path_;
这被称为“不是有效的严格弱排序”:
{ "a", "d" } < { "b", "c"}; because "a" < "b"
{ "b", "c" } < { "a", "d"}; because "c" < "d"
解决方法很简单:不要重新发明轮子:
return std::tie(a->filename_, a->path_) < std::tie(b->filename_, b->path_);
关于c++ - std::sort 中的错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48455244/