C ++ sort lambda比较器EXC_BAD_ACCESS

问题描述 投票:3回答:2

我遇到了这个奇怪的问题,以下代码抛出EXC_BAD_ACCESS错误。

using T = pair<int, bool>;
sort(vp.begin(), vp.end(), [](const T& a, const T& b) {
    return (a.first < b.first) || ((a.first == b.first) && a.second);
});

如果我跑:

using T = pair<int, bool>;
sort(vp.begin(), vp.end(), [](const T& a, const T& b) {
    return (a.first < b.first);
});

有用。如果我减少数据大小,它也可以。我很好奇((a.first == b.first) && a.second)做了什么导致错误?完整的数据源代码在这里:https://pastebin.com/r7muQhu7

我的环境:

Apple LLVM version 9.1.0 (clang-902.0.39.2)
Target: x86_64-apple-darwin17.7.0
c++ c++11 lambda exc-bad-access
2个回答
6
投票

你的lambda不满足排序比较函数所需的条件,即比较函数必须强加一个strict weak ordering(虽然在实践中你通常有一个total ordering)。

考虑到在你的情况下{1, true}小于{1, true},有些东西不能低于它本身。

这有效

return (a.first < b.first) || ((a.first == b.first) && (a.second < b.second));

同样如此

return (a.first < b.first) || ((a.first == b.first) && (a.second > b.second));

1
投票

以下代码抛出EXC_BAD_ACCESS错误[...]

我很好奇((a.first == b.first) && a.second)做了什么导致错误?

@john的答案完全以正确的方式解决了这个问题,并且就OP的错误做了很好的解释。我想添加为什么特别是可能抛出EXC_BAD_ACCESSstd::sort()的原因通常是使用Quick Sort实现的,stack overflow通常以递归方式编写。因此,你没有提供严格(弱)排序的事实,肯定会导致它进入一个无休止的递归,恰好在某个比自己小的比较点。即,无论操作数的顺序如何,比较都将返回true。这种无休止的递归是EXC_BAD_ACCESS的直接原因,因为您的程序试图使用比调用堆栈上可用空间更多的空间。在某些平台中,这转换为qazxswpoi信号。

© www.soinside.com 2019 - 2024. All rights reserved.