有人可以解释为什么以下排序会导致seg故障吗?这是g ++(指针的排序向量)的已知错误吗?我正在使用g ++ 4.5.2进行编译。
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
typedef vector<int> A;
bool face_cmp(const A *x, const A *y) {
return x != y;
}
int main(int argc, char* argv[]) {
vector<A *> vec;
for (int i=0; i<100; i++) {
vec.push_back( new vector<int>(i%100, i*i) );
}
vector<A *>::iterator it;
sort(vec.begin(), vec.end(), face_cmp);
return EXIT_SUCCESS;
}
在键盘上编译:
/usr/local/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../../include/c++/4.1.2/debug/safe_iterator.h:240:
error: attempt to decrement a dereferenceable (start-of-sequence)
iterator.
Objects involved in the operation:
iterator "this" @ 0x0xbf4b0844 {
type = N11__gnu_debug14_Safe_iteratorIN9__gnu_cxx17__normal_iteratorIPPN15__gnu_debug_def6vectorIiSaIiEEEN10__gnu_norm6vectorIS7_SaIS7_EEEEENS4_IS7_SB_EEEE (mutable iterator);
state = dereferenceable (start-of-sequence);
references sequence with type `N15__gnu_debug_def6vectorIPNS0_IiSaIiEEESaIS3_EEE' @ 0x0xbf4b0844
}
感谢您的所有快速回复。原始的comp函数是:
if (x == y) return false;
if (x->size() < y->size()) return true;
else if (x->size() > y->size()) return false;
else {
for (register int i=0; i<x->size(); i++) {
if ((*x)[i] < (*y)[i]) return true;
}
return false;
}
我刚刚更改了第一行并删除了其余部分。但事实证明它也不会受到严格的弱排序(如果(* x)[i]&gt;(* y)[i]我忘记了这种情况)。我应该已经发布了整个函数。不过,再次感谢!!
答案 0 :(得分:14)
比较函数必须定义严格的弱排序,这意味着a < b
和b < a
不能同时为真。您的比较函数没有此属性。
它没有定义任何“之前 - 之后”的关系,因此难怪依赖于此属性的算法无法正常运行。
答案 1 :(得分:8)
std::sort
的第三个参数应该是一个函数(或函数对象),如果compare(a, b)
是true
那么compare(b, a)
应该是false
,但是你的一个不是这样的。所以你的程序是UB,可以给出任何结果。
答案 2 :(得分:7)
没有你的代码是错的。 std :: sort的比较函数必须使用&lt;或它等效,使用!=不正确。可能你想要这个
bool face_cmp(const A *x, const A *y) {
return *x < *y;
}
答案 3 :(得分:1)
将比较函数定义为
bool face_cmp(const A *x, const A *y) {
return x < y;
}
答案 4 :(得分:0)
确保使用的是大于或小于。 请勿使用等于。等于将SEGFAULT与某些数据集:
// Good
bool face_cmp(const A *x, const A *y) {
return *x < *y;
}
// Also okay for reverse sorting
bool face_cmp(const A *x, const A *y) {
return *x > *y;
}
// This will SEGFAULT
bool face_cmp(const A *x, const A *y) {
return *x <= *y;
}
<=的真正危险是缺乏可重复性。我有一些SEGFAULT在Android上运行的C ++代码,同时在我的x86 PC上愉快地运行。对我来说,魔术数是68个元素,67个很好,68个SEGFAULT。