嗨,我在简单的程序上挣扎,在整数数组上执行lex排序
(完整程序:https://pastebin.com/UMqEP62n)
在足够大的int向量上运行排序会导致数组中出现随机数,然后依赖于导致segfault的数据.
sort(nums.begin(), nums.end(), lex_compare);
Run Code Online (Sandbox Code Playgroud)
比较功能:
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;
}
Run Code Online (Sandbox Code Playgroud)
基本上,当数组太长时,内存损坏会出现堆缓冲区溢出.使用地址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
Run Code Online (Sandbox Code Playgroud)
这本质上是lex_compare函数的第一行:
int ap = a, bp = b;
Run Code Online (Sandbox Code Playgroud)
我无法弄清楚导致这种行为的错误吗?是因为比较功能的大小?或者我有一些明显的内存读取错误?我使用clang 4.2.1,但其他平台也会导致相同的行为,因此我认为sort函数存在根本性的错误.
您的问题是违反了传递给比较函数的比较要求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;
Run Code Online (Sandbox Code Playgroud)
部分比较功能.由于尺寸相等,它会返回true.当我们翻转它并评估comp(b, a)我们到达同一个区块并将true再次返回时.
你需要在false什么时候回来,a == b而你却不这样做.
| 归档时间: |
|
| 查看次数: |
212 次 |
| 最近记录: |