C++ map自定义比较函数遵守严格弱序
问题背景及定位
背景:这个问题是在将tablesaw(一个Java的数据处理项目)迁移到C++时出现的。
问题位置:SplitOn()函数,在数据流水线中的aggregate阶段。
问题描述:使用google/benchmark进行了批量化的性能测试,在测试中出现偶发性段错误,几率大约在万分之一到十万分之一之间。
问题定位:由于开发环境为受限环境,无法使用GDB调试查看堆栈定位,只能使用打印日志的方式处理
定位问题出现在如下代码处:
struct ByteArrayCompare {
bool operator()(const ByteArray 服务器托管网&a, const ByteArray &b) const {
for (int i = 0; i selectionMap;
......
selectionMap[instanceByteArray] = std::move(selection); # crash here
至此,我个人百思不得其解,按照常理来说,应该是没有问题的。在没有段错误的情况下,测试用例能够顺利通过。
刚开始以为是class Selection的右值引用问题,有内存分配/释放没有构造/析构好,或者是移动构造出现问题,经过思考和检查排除以上问题。
因此定位问题出现在map自定义的ByteArrayCompare函数上。
map定义参见文档:https://cplusplus.com/reference/map/map/
template , //map::key_compare
class Alloc = allocator> //map::allocator_type
> class map;
由以上代码可见,map是可以自定义Compare比较函数和Alloc分配器的,此处就使用了自定义的Compare比较函数,应用于ByteArray数据类型。
题外话:unordered_map可以自定义hash和equal函数,这也体现了STL对于两种数据结构的不同实现方式,此处不再展开。
问题原因及解决方案
这里我们需要一个概念strict_weak_order(严格弱序)
本篇文章在数学和语义上阐述了严格弱序的意义,值得一看:https://zhuanlan.zhihu.com/p/378294506
抛开复杂的逻辑不谈,简单来说,该性质要求比较函数对于两个不同的key,改变输入顺序不会服务器托管网改变比较结果。
例:(a, b)形式输入,输出结果为a
具体到我们此处的代码:此时我们已经遍历完成了a和b中较短的那个,但是对于剩余长度,没有进行比较,而是直接返回true,因此出现了上述的非严格弱序问题。
修改后代码:
struct ByteArrayCompare {
bool operator()(const ByteArray &a, const ByteArray &b) const {
for (int i = 0; i selectionMap;
......
selectionMap[instanceByteArray] = std::move(selection); # crash here
至此,再进行测试后不会出现上述段错误问题,问题解决。
服务器托管,北京服务器托管,服务器租用 http://www.fwqtg.net
机房租用,北京机房租用,IDC机房托管, http://www.fwqtg.net
写在开头 之前更新了不少Java的基础知识,比如Java的类、对象、基础类型、关键字、序列化、泛型、值传递等等,今天要上点深度了,来聊一聊Java中的 反射 ! 所谓反射,就是在运行时分析、检查和操作类、接口、方法、属性的行为! 简单感受一下反射 在开始详解反…