首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >比较函数应该这样写

比较函数应该这样写

作者头像
用户5521279
发布于 2019-07-31 03:03:47
发布于 2019-07-31 03:03:47
7870
举报
文章被收录于专栏:搜狗测试搜狗测试

近期在review开发代码时,发现有这样的一类提交,开发把所有比较函数中的等号都去掉了,类似这样。

聪明的小编开始思考,开发为啥要这样做呢?经过和开发的沟通了解,发现一条小编不清楚的comp函数的“Strict Weak Ordering”原理,如果比较函数编写不得当,那么很有可能会使代码coredump,从而带来严重的质量隐患。

core的原因是什么呢,c++ 标准库 sort() 在对基础类型排序时,直接调用 sort(start,end) 即可,对于非基础类型的结构体,可以通过重载函数提供一个比较函数。sort() 的内部排序使用插入排序和快速排序,当sort函数选择快速排序时,根据快排规则,如果当比较元素相同返回真时,此时比较元素将会继续向下遍历,在极端情况下,例如程序中所有元素都是一样的情况下,就会出现访问越界,结果就是导致程序出现segment fault。

那么什么样的比较函数才是足够安全健壮的呢,已经有一套规则去对比较函数进行约束,

如果一个comp函数要满足“Strict Weak Ordering”,

意味着它应该满足如下特征:(https://en.wikipedia.org/wiki/Weak_ordering#Strict_weak_orderings):

(a) 反自反性:也即comp(x, x)必须是false

(b) 非对称性:也即如果comp(x, y)和comp(y, x)的结果必然相反

(c) 可传递性:也即如果comp(x, y)为true,comp(y, z)为true,那么comp(x, z)必然为true

小编写了代码去验证这个问题,发现sort函数已经对代码的弱序化进行了校验和保护,当排序内容大小一致时,且规则中包含等号,则会命中以下异常。

虽然在sort函数上这个问题已经添加了保护校验,但是我们自己编写的排序器和比较函数也应该注意满足“Strict Weak Ordering”,避免访问越界等其他意外再次发生。

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-07-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 搜狗测试 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
std::sort coredump 说起
c++ 标准库 sort() 默认采用 < 这个 operator 来排序的, 另个一个重载函数增加第三个参数,指定一个比较的函数,函数接受两个参数。 对于基础类型(int,float..),直接调用 sort(start,end) 即可,对于非基础类型的结构体,可以通过重载对象的 < 运算符或者提供一个比较函数。 详见
orientlu
2018/09/13
1.9K0
【线上问题】P1级公司故障,年终奖不保
前段时间,某个同事找我倾诉,说是因为strict weak ordering导致程序coredump,给公司造成数百万损失,最终评级故障为P0级,年终奖都有点不保了,听完不禁一阵唏嘘。
高性能架构探索
2022/08/25
5580
【线上问题】P1级公司故障,年终奖不保
Reddit 观察 | 以排序为案例,对 C/CPP/Rust 安全与性能的相关性研究
在用户定义的比较函数中,复杂的通用实现与追求性能的组合,使得通用高性能排序实现在避免每种使用场景下的未定义行为(UB)方面特别困难。即使只使用内存安全的抽象来实现排序,也不能保证相邻逻辑是无未定义行为的。
张汉东
2023/10/06
5530
Reddit 观察 | 以排序为案例,对 C/CPP/Rust 安全与性能的相关性研究
C++中sort函数使用方法
1.sort函数包含在头文件为#include<algorithm>的c++标准库中,调用标准库里的排序方法可以实现对数据的排序,但是sort函数是如何实现的,我们不用考虑!
狼啸风云
2020/07/20
1.9K0
C++中sort函数使用方法
C++ STL学习之容器set和multiset (补充材料)
一、set和multiset基础 set和multiset会根据特定的排序准则,自动将元素进行排序。不同的是后者允许元素重复而前者不允许。 需要包含头文件: #include <set> set和mu
Angel_Kitty
2018/04/08
1.2K0
C++ STL学习之容器set和multiset (补充材料)
sort函数对vector排序_sort函数对结构体数组排序
今天写代码的是遇到想对vector进行排序的问题,隐约记得std::sort函数是可以对vector进行排序的,但是这次需要排序的vector中压的是自己定义的结构体(元素大于等于2),想以其中某一个元素进行正序或逆序排序,则不能直接使用sort函数。
全栈程序员站长
2022/09/21
2K0
【C指针(五)】6种转移表实现整合longjmp()/setjmp()函数和qsort函数详解分析&&模拟实现
本小节,我们将继续学习C语言转移表,什么是回调函数,回调函数又是什么?qsort函数怎么使用,怎么理解处理,要注意的细节,当然qsort使用举例,最后我们进行qsort函数的模拟实现!文章干货满满,走起!
学习起来吧
2024/02/29
5460
【C指针(五)】6种转移表实现整合longjmp()/setjmp()函数和qsort函数详解分析&&模拟实现
图解|从武侠角度探究STL排序算法的奥秘
众所周知STL是借助于模板化来支撑数据结构和算法的通用化,通用化对于C++使用者来说已经很惊喜了,但是如果你看看STL开发者强大的阵容就意识到STL给我们带来的惊喜绝不会止步于通用化,强悍的性能和效率是STL的更让人惊艳的地方。
C语言与CPP编程
2021/07/27
4890
图解|从武侠角度探究STL排序算法的奥秘
qsort(),sort()排序函数
一.qsort()函数 功 能: 使用快速排序例程进行排序 头文件:stdlib.h 用 法: void qsort(void *base,int nelem,int width,int (*fcmp)(const void *,const void *)); 参数: 1 待排序数组首地址 2 数组中待排序元素数量 3 各元素的占用空间大小 4 指向函数的指针,用于确定排序的顺序 qsort(即,quicksort)主要根据你给的比较条件给一个快速排序,主要是通过指针移动
猿人谷
2018/01/17
2.2K0
Python中sort与sorted函数
python中列表的内置函数sort()可以对列表中的元素进行排序,而全局性的sorted()函数则对所有可迭代的序列都是适用的;
全栈程序员站长
2022/11/15
7580
【C语言篇】深入理解指针4(模拟实现qsort函数)
如果你把函数的指针(地址)作为参数传递给另⼀个函数,当这个指针被⽤来调⽤其所指向的函数时,被调⽤的函数就是回调函数。
半截诗
2024/10/09
1230
【C语言篇】深入理解指针4(模拟实现qsort函数)
Effective STL(21) 永远让比较函数对相同元素返回false
问题描述: 昨天一哥们些的程序,在定义比较函数的时候是这样写的 bool cmp(const T& a, const T& b) { if (a >= b) return true; return false; } 在内部测试时,一直表现挺好,也没挂。 但一到线上,立即就挂了,打印出vector内的元素也都是正确的, 但是core在了 STL:sort里面了, 而且指针明显也是错的了。 原因分析: stl:sort 排序 如果数据过多 才会用快速排序 所有数据进行与中间值
早起的鸟儿有虫吃
2018/04/13
1.8K0
Effective STL(21) 永远让比较函数对相同元素返回false
【C++修行之道】竞赛常用库函数(sort,min和max函数,min_element和max_element、nth_element)
sort函数用于C++中,对给定区间所有元素进行排序,默认为升序,也可进行降序排序。
走在努力路上的自己
2024/01/26
5580
【C++修行之道】竞赛常用库函数(sort,min和max函数,min_element和max_element、nth_element)
9.1 C++ STL 排序、算数与集合
C++ STL(Standard Template Library)是C++标准库中的一个重要组成部分,提供了丰富的模板函数和容器,用于处理各种数据结构和算法。在STL中,排序、算数和集合算法是常用的功能,可以帮助我们对数据进行排序、统计、查找以及集合操作等。
王 瑞
2023/08/17
2620
【C++】初探 map 与 set
关联式容器也是用来存储数据的,与序列式容器不同的是,其里面存储的是<key, value>结构的键值对,在数据检索时比序列式容器效率更高!
叫我龙翔
2024/05/26
1090
【C++】初探 map 与 set
浅析go切片与排序
切片是Go语言中引入的用于在大多数场合替代数组的语法元素。切片是一种长度可变的同类型元素序列,它原则上不支持存储不同类型的元素,当然了作为打工人是非常清楚“原则上”的潜台词就是“某种情况下允许”
Yerik
2021/04/16
6050
【C语言】剖析qsort函数的实现原理
回调函数实际上是一个指针,指向的是一个函数。它作为一个参数传递给另一个函数,并且在特定的条件下被执行。
DevKevin
2024/03/19
3410
【C语言】剖析qsort函数的实现原理
C++20新特性—“宇宙飞船”运算符
三路运算符是由Herb Sutter提出,2019年10月8日确定的C++20草案中正式将三路运算符纳入进来。在类中使用三路运算符后,编译器可以默认生成6个基础运算符,这一新特性的使用从一定程度上来说减少了开发的工作量,因此也受到大家的喜爱,被大家称为:宇宙飞船运算符。
CPP开发前沿
2021/12/04
2.4K0
【算法】快速排序算法的编码和优化
根据文章内容撰写摘要总结
啦啦啦321
2018/01/03
1.7K0
【算法】快速排序算法的编码和优化
Python冒泡排序算法及其优化「建议收藏」
所谓冒泡,就是将元素两两之间进行比较,谁大就往后移动,直到将最大的元素排到最后面,接着再循环一趟,从头开始进行两两比较,而上一趟已经排好的那个元素就不用进行比较了。(图中排好序的元素标记为黄色柱子)
全栈程序员站长
2022/11/04
8240
Python冒泡排序算法及其优化「建议收藏」
推荐阅读
相关推荐
std::sort coredump 说起
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档