Std::nth_element crash problems
(1) Source code:
- Auto Less_compare = [] (const mirroringgroup& MG1, const mirroringgroup& MG2), bool {
- Return (Mg1.usage () < Mg2.usage ());
- };
(2) Questions:
Often occurs crash,stack as follows:
- #0 0x00000000004b3807 in Mirroringgroup::copyfrom (This=0x15edf20, from= ...) at miuifs/miuistorage-dev/idl/proto/ internaldata.pb.cc:6487
- #1 0x000000000052bc71 in mirroringgroup::operator= (This=0x15edf20, from= ...) at miuifs/miuistorage-dev/idl/proto/ internaldata.pb.h:1797
- #2 0X000000000052F7CB in Std::swap (__a= ..., __b= ...) at/usr/local/include/c++/4.8.2/bits/move.h:177
- #3 0x000000000052e0b0 in Std::iter_swap<__gnu_cxx::__normal_iterator >, __gnu_cxx:: __normal_iterator > > > (__a=, __b= ...)
- at/usr/local/include/c++/4.8.2/bits/stl_algobase.h:147
- #4 0x0000000000604b11 in Std::__unguarded_partition<__gnu_cxx::__normal_iterator , Mirroringgroup, miuifs::blockmanager::choosewritablemirroringgroups (std::vector) mirroringgroup> *, int)::__lambda101> (__gnu_cxx::__normal_iterator >, __gnu_cxx::__normal_iterator >, const mirroringgroup &, miuifs::blockmanager::__lambda101) (__fi Rst= ..., __last= ..., __pivot= ..., __comp= ...) at/usr/local/include/c++/4.8.2/bits/stl_algo.h:2270
- #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) (
- __first= ..., __last= ..., __comp= ...) at/usr/local/include/c++/4.8.2/bits/stl_algo.h:2296
- #6 0x0000000000603408 in Std::__introselect<__gnu_cxx::__normal_iterator ;, long int, miuifs::blo Ckmanager::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,
- __comp= ...) at/usr/local/include/c++/4.8.2/bits/stl_algo.h:2394
- #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_ite Rator >, miuifs::blockmanager::__lambda101) (__first= ..., __nth= ..., __last= ..., __comp= ...)
- at/usr/local/include/c++/4.8.2/bits/stl_algo.h:5417
- #8 0x000000000060039c in Miuifs::blockmanager::choosewritablemirroringgroups (THIS=0X118ABE0 , mgs=0x7fffeb9f414 0,
- copy_count=2) at miuifs/miuistorage-dev/blockmanager.cc:391
- #9 0x00000000005ff9cf in Miuifs::blockmanager::newblock (THIS=0X118ABE0 ) at Miuifs/miuistorage-dev/blockmanager . cc:331
- #10 0x00000000005fed63 in Miuifs::blockmanager::acquireblock (THIS=0X118ABE0 , attribute= ...)
- At miuifs/miuistorage-dev/blockmanager.cc:243
(3) Find the problem:
Problem has been in the std::nth_element, began to think of STL is not the problem, has not been a good solution, and then read the STL source code to find the reason in/usr/local/include/c++/4.8.2/bits/stl_ In Algo.h:
- Template
- Inline _randomaccessiterator
- __unguarded_partition_pivot (_randomaccessiterator __first,
- _randomaccessiterator __last, _compare __comp)
- {
- _randomaccessiterator __mid = __first + (__last-__first)/2;
- Std::__move_median_to_first (__first, __first + 1, __mid, (__last-2),
- __COMP);
- Return Std::__unguarded_partition (__first + 1, __last, *__first, __comp);
The role of the __move_median_to_first function is to Exchange __first +1, __mid, (__last-2) in the middle size of the value and __first. But ignoring the __mid, (__last-2) points to the same iterator, if the input is as follows:
After __move_median_to_first, the results are as follows:
At this point, __first points to the maximum value. Then look at the implementation of Std::__unguarded_partition, in 2263 rows __comp (*__first, __pivot)) forever returns True, causing ++__first to execute and access the illegal memory.
- Template
- _randomaccessiterator
- __unguarded_partition (_randomaccessiterator __first,
- _randomaccessiterator __last,
- Const _tp& __pivot, _compare __comp)
- {
- while (true)
- {
- while (__comp (*__first, __pivot))
- ++__first;
- --__last;
- while (__comp (__pivot, *__last))
- --__last;
- if (! ( __first < __last))
- return __first;
- Std::iter_swap (__first, __last);
- ++__first;
- }
(4) Workaround:
Through Google find the following link, found that is really a STL bug, can only be resolved by upgrading C + +.
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=732042
http://www.bkjia.com/PHPjc/1071768.html www.bkjia.com true http://www.bkjia.com/PHPjc/1071768.html techarticle std::nth_element crash problem (1) Source: Auto Less_compare = [] (const mirroringgroup MG2), bool {return (Mg1.usage ()}; Std::nth_element (Mgs->begin (), Mgs->begin () + (Copy_co ...