问题描述
在leetcode上做题目的时候,用到了stl的sort
函数,给vector排序,程序大致如下:
...
sort(test.begin(), test.end(), [](auto &lhs, auto &rhs) {
return lhs <= rhs;
});
...
提交之后,通过了部分用例,然后执行失败,leetcode的给出的执行出错信息比较奇怪,如下:
runtime error: reference binding to misaligned address 0xbebebebebebebebe for type 'const value_type', which requires 4 byte alignment (stl_vector.h)
这条错误信息字面上看是引用绑定到了未对齐的地址,在一些体系结构下,访问未对齐的地址是会引发异常的,但是怎么检查程序也没有发现有未对齐地址,总不至于链接器故意把变量往未对齐的地址上安排吧。
原因分析
因为无法从leetcode给出的执行错误信息找到线索,所以还是决定用IDE调试下,看看问题何在。首先使用了codeblock17.12作为调试工具,编译环境是其自带的GCC编译器。对于没有引发问题的用例,程序可以顺利运行,而对于引发问题的用例,codeblock表现的也很怪异:程序运行后很持续很长时间才退出,唯一的线索是:Process returned -1073741819 (0xC0000005) execution time : 13.203 s
。
无奈换用vs的编译环境,这回很快就发现了问题:
弹窗给出的invalid comparator反映出了问题所在,stl的sort函数需要提供一个比较函数comp
(有默认版本),而该比较函数需要满足严格弱序的条件,何谓严格弱序?根据标准库手册的描述,comp
需要满足如下属性:
- 对于任一变量a,comp(a,a)为
false
- 如果comp(a,b) 为
true
,那么comp(b,a)为false
- 如果comp(a,b)为
true
且comp(b,c)true
,则comp(a,c)为true
通俗一点解读上面的要求:通常,2个对象的大小关系有3种,小于、等于以及大于。严格弱序要求忽略等于,即两个对象之间的比较只剩两种情况,小于以及不小于
,或者是大于以及不大于
(取决于升序还是降序)。
我使用lambda表达式提供的比较函数不满足严格弱序的条件,所以才出了问题。其实这个问题本身没什么可说的,只是leetcode、codeblock在程序出错时给的反馈实在太奇怪了,这给了我一个经验教训,以后再遇到奇奇怪怪的现象,不妨换一个编译环境,没准就能获得比较靠谱的错误提示了。
解决方案
弄清楚问题在哪,解决起来就简单了,将:
sort(test.begin(), test.end(), [](auto &lhs, auto &rhs) {
return lhs <= rhs;
});
改成
sort(test.begin(), test.end(), [](auto &lhs, auto &rhs) {
return lhs < rhs;
});