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

Mik*_*e B 5 c++ sorting gcc gnu std

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;
}
Run Code Online (Sandbox Code Playgroud)

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

stl排序 - 严格的弱排序

因此,如果:

  (a < b) == true, (b < a) must be false.
Run Code Online (Sandbox Code Playgroud)

另外,如果:

   a == b, then (a < b) and (b < a) are false.
Run Code Online (Sandbox Code Playgroud)

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

 (1, 3) (-1, 2), (3, 1)
Run Code Online (Sandbox Code Playgroud)

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

  a < b, and b < c, but c < a.
Run Code Online (Sandbox Code Playgroud)

这个答案:导致std :: sort()访问超出范围的地址的原因解释了为什么当比较函数不尊重irreflexibility时std :: sort将解决越界(例如,我们做comp的快速排序(pivot) ,pivot)并得到true,因此左指针一直向右走离数组的末尾.

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

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

我想知道的是,如果有人知道为什么当比较是非传递的时,std :: sort会在GNU C++下崩溃?我知道,非过渡比较撕毁合同,它是不确定的行为,但我希望有一个类似的答案,一个在链接的问题-即正是为什么它会崩溃.