嗨,我在简单的程序上苦苦挣扎,该程序对整数数组进行lex排序
(完整程序在这里:https://pastebin.com/UMqEP62n)
在足够大的整数向量上运行排序会导致随机数出现在数组中,然后取决于导致段错误的数据。
sort(nums.begin(), nums.end(), lex_compare);
比较功能:
bool lex_compare(const int &a, const int &b) {
int ap = a, bp = b;
vector<int> da, db;
if (ap == 0) da.insert(da.begin(), ap%10);
while (ap > 0) {
da.insert(da.begin(), ap%10);
ap /= 10;
}
if (bp == 0) db.insert(db.begin(), bp%10);
while (bp > 0) {
db.insert(db.begin(), bp%10);
bp /= 10;
}
size_t size;
if (da.size() < db.size()) {
size = da.size();
} else {
size = db.size();
}
for (size_t i = 0; i < size; ++i)
if (da[i] > db[i])
return true;
else if (da[i] < db[i])
return false;
else
continue;
if (da.size() > db.size())
return false;
else
return true;
}
基本上,当数组太长时,由于堆缓冲区溢出,会出现内存损坏。使用地址Sanitizer编译时,它显示:
==4097==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6140000001d0 at pc 0x00010aa396fe bp 0x7ffee51c5c50 sp 0x7ffee51c5c48
READ of size 4 at 0x6140000001d0 thread T0
#0 0x10aa396fd in lex_compare(int const&, int const&) main.cpp:8
实质上是lex_compare函数的第一行:
int ap = a, bp = b;
在这里我无法弄清楚哪种错误会导致这种现象?是由于比较功能的大小吗?还是我有一些明显的内存读取错误?我使用的是clang 4.2.1,但其他平台也会引起相同的行为,因此我认为排序功能存在根本性的错误。
答案 0 :(得分:5)
您的问题是您违反了compare requirement的要求,传递给std::sort
的比较函数必须遵循。
比较要求要求如果为comp(a,b)==true
,则为comp(b,a)==false
,但比较函数不能执行此操作。例如,如果a = 0
和b = 0
,那么comp(a, b)
会将您带到
if (da.size() > db.size())
return false;
else
return true;
比较功能的一部分。由于大小相等,因此返回true
。当我们翻转它并评估comp(b, a)
时,我们会到达相同的块,并将再次返回true
。
您需要在false
时返回a == b
,但您不这样做。