为什么std :: sort segfault与非传递比较器?

时间:2017-08-09 19:52:04

标签: c++ sorting gcc std gnu

struct Object
{
    int x;
    int y;
    bool isXValid()
    {
       return x > 0;
    }
};

bool mySort(const Object& lhs, const Object& rhs)
{
    // Note the short-circuit here
    bool isValidForCheck = lhs.isXValid() && rhs.isXValid();

    // rhs may be valid because short-circuit, or both may be invalid
    if (isValidForCheck)
    {
       return lhs.x < rhs.x;
    }

    return lhs.y < rhs.y;
}

int main()
{
    std::vector<Object> myVec;
    // random populating of myVec
    std::sort(myVec.begin(), myVec.end(), mySort);
    return 0;
}

我的比较函数是反射性的,但不尊重传递性。

stl ordering - strict weak ordering

因此,如果:

  (a < b) == true, (b < a) must be false.

此外,如果:

   a == b, then (a < b) and (b < a) are false.

但是,它不具有传递性。例如,使用以下值:

 (1, 3) (-1, 2), (3, 1)

然后可以生成一个已排序的容器:

  a < b, and b < c, but c < a.

这个答案:What causes std::sort() to access address out of range解释了当比较函数不尊重irreflexibility时,为什么std :: sort将解决越界问题(例如,我们执行comp(pivot,pivot)并获得true的quicksort) ,因此左指针一直走在数组的末端。)

但是,我看到崩溃的比较是反射性但不可传递的。我也相信我会离开阵列的末尾。

我无法提供确切的代码,因为它是专有的。上面的例子在我的测试中不会崩溃,但我知道std :: sort会根据容器和要排序的元素选择不同的算法。

我想知道的是,如果有人知道为什么当比较不可传递时,std :: sort会在GNU C ++下崩溃?我知道非传递性比较打破了合同并且它是未定义的行为,但我希望在链接问题中找到类似的答案 - 即正好为什么它会崩溃。

0 个答案:

没有答案