调用sort段错误问题

问题:sort的比较函数实现有问题致使进程调用sort时core了。
结论:特别要注意, sort的比较函数必须遵循严格弱排序(strict weak ordering)的规则。
 
这是最近在工做中遇到的一个问题,平时用函数就简单看了函数原型和例子,如无须要,没有去细究太多。结果在sort的使用就碰钉子,今天分享出来,你们也给本身提个醒。很少赘述,直接贴代码。
 
1. std::sort的调用
 
2. 比较函数compareFriUser
 
编译是没问题的,可是运行到这里就会致使core。core的堆栈以下:
 
 
第一次见到这样的core文件,当时第一感受是怀疑<algorithm>提供的sort的排序算法是否是有问题,固然这么怀疑一个通过历史洗礼的标准库是很蠢的事情。
后面在网上找到了问题所在。
咱们所使用的sort原型是这样:
template <class RandomAccessIterator, class Compare>
  void sort (RandomAccessIterator first, RandomAccessIterator last, Compare comp);

手册中对于第三个参数的说明是这样(http://www.cplusplus.com/reference/algorithm/sort/?kw=sort ):html

comp
Binary function that accepts two elements in the range as arguments, and returns a value convertible tobool. The value returned indicates whether the element passed as first argument is considered to go before the second in the specific strict weak ordering it defines.
The function shall not modify any of its arguments.
This can either be a function pointer or a function object.
(翻译:comp是一个接受两个表示范围的元素做为参数的二元函数,它返回一个可转成bool的值。返回值指示了在comp定义的特定的严格弱排序中,第一个参数是否应该排在第二个参数以前。comp函数不会改变任何一个参数,它能够是一个函数指针或一个仿函数。)
 
咱们注意到该说明提到了comp参数必须是严格弱排序。网上的一个较好的解读是: 严格是说在判断的时候会用"<",而不是"<=",弱排序是由于,一旦"<"成立便认为存在"<"关系,返回ture,而忽略了"="关系和">"区别,把它们归结为false。相关定义能够参阅: http://www.sgi.com/tech/stl/StrictWeakOrdering.html
简单说,在comp中,当参数1和参数2等价时,必须返回false.
在截图中的compareFriUser中,CSGameUser的等价条件是online、hasMsg、m_vip_level都相等,参数1既不小于参数2,参数2也不小于参数1,此时二者等价。
而在中,当 p1->m_vip_level == p2->m_vip_level ,却返回了1. 这就违反了严格弱序的定义,会致使不可预估的结果。
在这里,咱们只要把这句代码改为 p1->m_vip_level > p2->m_vip_level  ,问题就解决了。
 
而这样的比较函数之因此会致使sort内部调用core是由于sort内部的排序函数不会进行边界检查,而p1->m_vip_level == p2->m_vip_level 时return true会致使其取到不正确的元素地址。关于这个问题,可参考该连接:http://verihy.me/posts/stdsort-cmp-order/
(该问题能够去仔细研读sort的具体实现)
 
关于以上的问题,在《Effective STL》的条款20和21都有提到,《STL源码剖析》关于sort函数源码也有详细的解读。你们能够去阅读一下。尤为是STL中有不少很好用的函数和数据结构,在没有仔细阅读使用手册的状况下,按照本身的理解去使用它们有时会致使出现不可预估的结果,这个时候参阅这两本书籍和说明文档是十分有用的。
相关文章
相关标签/搜索