C++ 如果比较函数不是as运算符<;,为什么std::sort会崩溃;?
下面的程序是用VC++2012编译的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
#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解释得很好:Youcomp
函数说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如果运气好的话,它会默默地传送您的数据。