C++ 如果比较函数不是as运算符<;,为什么std::sort会崩溃;?

C++ 如果比较函数不是as运算符<;,为什么std::sort会崩溃;?,c++,algorithm,exception,standards,C++,Algorithm,Exception,Standards,下面的程序是用VC++2012编译的 #include <algorithm> struct A { A() : a() {} bool operator <(const A& other) const { return a <= other.a; } int a; }; int main() { A coll[8]; std::sort(&coll[0

下面的程序是用VC++2012编译的

#include <algorithm>

struct A
{
    A()
        : a()
    {}

    bool operator <(const A& other) const
    {
        return a <= other.a;
    }

    int a;
};

int main()
{
    A coll[8];
    std::sort(&coll[0], &coll[8]); // Crash!!!
}
#包括
结构A
{
()
:a()
{}

bool操作员
std::sort
需要满足严格弱排序规则的分拣机,这一规则已解释


因此,你的比较器说,当
a==b
不遵循严格弱排序规则时,算法可能会崩溃,因为它将进入无限循环。

xorguy的答案非常好

我只想引用一下标准:

25.4排序和相关操作[alg.排序]

为了使25.4.3中描述的算法以外的算法正常工作,comp必须对值进行严格的弱排序。

术语“严格”指的是不可伸缩关系的要求(!comp(x,x)适用于所有x),术语“弱”指的是要求不如总排序的要求强,但比部分排序的要求强


所以xorguy解释得很好:You
comp
函数说
a
a==b
不遵循严格弱排序规则时…

代码的问题是访问的内存无效。code

coll[8]
尝试访问最后一个数组元素之后的元素(最后一个元素索引为7)。 我建议使用std::array代替普通的C数组

std::array<A, 8> a;

// fill it somehow

std::sort(a.begin(), a.end());
std::数组a;
//用某种方法填满它
排序(a.begin(),a.end());

std::sort的比较器需要严格的弱排序,
你应该为一个向量写一个(0)…但它不会在这里崩溃!@LaszloPapp:是的。它的值初始化
a()
(这就是
a()
的意思),对于
int
表示0。@LaszloPapp:请将未定义的行为&coll[8]替换为coll+8+1这说明了
std::sort
的比较器的要求。如果编译器符合C++11(并且OPs符合;VS2012),我将使用
std::sort(std::begin(coll),std::end(coll));
。如果您更改了数组的维度,或者使用了任何标准容器,您会很高兴。进入无限循环只会导致它卡住。相反,它会转储核心。为什么?@b我想这是因为
std::sort
使用递归算法,在无限循环的情况下会导致堆栈溢出。哟你必须了解它检查的具体内容,但是标准排序例程的运行速度非常非常快,所以它们不会检查你做的每件事是否正常,它们只是依靠它。如果你的比较返回了不可能的结果,那么不可能的事情就会发生——说它得到了一些比较的结果,然后如果将其用作查找位置的索引,则只有它“知道”哪些值是可能的,并且“知道”生成的引用将位于有效存储中,因此它只会获取它。Kaboom:SIGSEGV如果运气好的话,它会默默地传送您的数据。