0

0

std::nth_element crash问题

php中文网

php中文网

发布时间:2016-06-13 08:50:57

|

1414人浏览过

|

来源于php中文网

原创

std::nth_element crash问题

(1) 源码:

  1. auto less_compare = [] (const MirroringGroup& mg1, const MirroringGroup& mg2) -> bool {
  2. return (mg1.usage() < mg2.usage());
  3. };
  4. std::nth_element(mgs->begin(), mgs->begin() + (copy_count - 1), mgs->end(), less_compare);

(2) 问题:

经常发生crash,stack如下:

  1. #0 0x00000000004b3807 in MirroringGroup::CopyFrom (this=0x15edf20, from=...) at miuifs/miuistorage-dev/idl/proto/InternalData.pb.cc:6487
  2. #1 0x000000000052bc71 in MirroringGroup::operator= (this=0x15edf20, from=...) at miuifs/miuistorage-dev/idl/proto/InternalData.pb.h:1797
  3. #2 0x000000000052f7cb in std::swap (__a=..., __b=...) at /usr/local/include/c++/4.8.2/bits/move.h:177
  4. #3 0x000000000052e0b0 in std::iter_swap<__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > > > (__a=..., __b=...)
  5. at /usr/local/include/c++/4.8.2/bits/stl_algobase.h:147
  6. #4 0x0000000000604b11 in std::__unguarded_partition<__gnu_cxx::__normal_iterator >, MirroringGroup, miuifs::BlockManager::ChooseWritableMirroringGroups(std::vector*, int)::__lambda101>(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, const MirroringGroup &, miuifs::BlockManager::__lambda101) (__first=..., __last=..., __pivot=..., __comp=...) at /usr/local/include/c++/4.8.2/bits/stl_algo.h:2270
  7. #5 0x0000000000603c1b in std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator >, miuifs::BlockManager::ChooseWritableMirroringGroups(std::vector*, int)::__lambda101>(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, miuifs::BlockManager::__lambda101) (
  8. __first=..., __last=..., __comp=...) at /usr/local/include/c++/4.8.2/bits/stl_algo.h:2296
  9. #6 0x0000000000603408 in std::__introselect<__gnu_cxx::__normal_iterator >, long int, miuifs::BlockManager::ChooseWritableMirroringGroups(std::vector*, int)::__lambda101>(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, long, miuifs::BlockManager::__lambda101) (__first=..., __nth=..., __last=..., __depth_limit=2,
  10. __comp=...) at /usr/local/include/c++/4.8.2/bits/stl_algo.h:2394
  11. #7 0x0000000000602c95 in std::nth_element<__gnu_cxx::__normal_iterator >, miuifs::BlockManager::ChooseWritableMirroringGroups(std::vector*, int)::__lambda101>(__gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, __gnu_cxx::__normal_iterator > >, miuifs::BlockManager::__lambda101) (__first=..., __nth=..., __last=..., __comp=...)
  12. at /usr/local/include/c++/4.8.2/bits/stl_algo.h:5417
  13. #8 0x000000000060039c in miuifs::BlockManager::ChooseWritableMirroringGroups (this=0x118abe0 , mgs=0x7fffeb9f4140,
  14. copy_count=2) at miuifs/miuistorage-dev/BlockManager.cc:391
  15. #9 0x00000000005ff9cf in miuifs::BlockManager::NewBlock (this=0x118abe0 ) at miuifs/miuistorage-dev/BlockManager.cc:331
  16. #10 0x00000000005fed63 in miuifs::BlockManager::AcquireBlock (this=0x118abe0 , attribute=...)
  17. at miuifs/miuistorage-dev/BlockManager.cc:243

(3) 查找问题:

问题一直出现在std::nth_element中,开始没有想到是STL的问题,一直没有很好的解决办法,后来通过阅读STL源码找到原因在/usr/local/include/c++/4.8.2/bits/stl_algo.h中:

  1. template
  2. inline _RandomAccessIterator
  3. __unguarded_partition_pivot(_RandomAccessIterator __first,
  4. _RandomAccessIterator __last, _Compare __comp)
  5. {
  6. _RandomAccessIterator __mid = __first + (__last - __first) / 2;
  7. std::__move_median_to_first(__first, __first + 1, __mid, (__last - 2),
  8. __comp);
  9. return std::__unguarded_partition(__first + 1, __last, *__first, __comp);
  10. }

__move_median_to_first函数的作用是将 __first +1 , __mid, (__last - 2) 中中间大小的值和 __first交换。但是却忽略了__mid,(__last - 2) 指向相同迭代器的情况,如果输入时情况如下:


经过__move_median_to_first之后的结果如下:


此时__first指向了最大的值。然后看std::__unguarded_partition的实现,在2263行__comp(*__first, __pivot))永远返回true,导致++__first一直执行而访问了非法内存。


  1. template
  2. _RandomAccessIterator
  3. __unguarded_partition(_RandomAccessIterator __first,
  4. _RandomAccessIterator __last,
  5. const _Tp& __pivot, _Compare __comp)
  6. {
  7. while (true)
  8. {
  9. while (__comp(*__first, __pivot))
  10. ++__first;
  11. --__last;
  12. while (__comp(__pivot, *__last))
  13. --__last;
  14. if (!(__first < __last))
  15. return __first;
  16. std::iter_swap(__first, __last);
  17. ++__first;
  18. }
  19. }

(4) 解决方法:

通过google找到下面这个链接,发现确实是一个STL的bug,只能通过升级C++解决了。

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=732042

Pixlr
Pixlr

Pixlr是一款2008年推出的在线图片编辑和AI图片处理工具,目前已推出AI 图像生成器、AI 生成填充、AI 删除背景、AI 删除对象和 AI 图像扩展等现代 AI 工具。

下载




相关标签:

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
Word 字间距调整方法汇总
Word 字间距调整方法汇总

本专题整合了Word字间距调整方法,阅读下面的文章了解更详细操作。

2

2025.12.24

任务管理器教程
任务管理器教程

本专题整合了任务管理器相关教程,阅读下面的文章了解更多详细操作。

2

2025.12.24

AppleID格式
AppleID格式

本专题整合了AppleID相关内容,阅读专题下面的文章了解更多详细教程。

0

2025.12.24

csgo视频观看入口合集
csgo视频观看入口合集

本专题整合了csgo观看入口合集,阅读下面的文章了知道更多入口地址。

29

2025.12.24

yandex外贸入口合集
yandex外贸入口合集

本专题汇总了yandex外贸入口地址,阅读下面的文章了解更多内容。

58

2025.12.24

添加脚注通用方法
添加脚注通用方法

本专题整合了添加脚注方法合集,阅读专题下面的文章了解更多内容。

1

2025.12.24

重启电脑教程汇总
重启电脑教程汇总

本专题整合了重启电脑操作教程,阅读下面的文章了解更多详细教程。

3

2025.12.24

纸张尺寸汇总
纸张尺寸汇总

本专题整合了纸张尺寸相关内容,阅读专题下面的文章了解更多内容。

5

2025.12.24

Java Spring Boot 微服务实战
Java Spring Boot 微服务实战

本专题深入讲解 Java Spring Boot 在微服务架构中的应用,内容涵盖服务注册与发现、REST API开发、配置中心、负载均衡、熔断与限流、日志与监控。通过实际项目案例(如电商订单系统),帮助开发者掌握 从单体应用迁移到高可用微服务系统的完整流程与实战能力。

1

2025.12.24

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Excel 教程
Excel 教程

共162课时 | 9.3万人学习

Java 教程
Java 教程

共578课时 | 36.8万人学习

Uniapp从零开始实现新闻资讯应用
Uniapp从零开始实现新闻资讯应用

共64课时 | 6.4万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号