zoukankan      html  css  js  c++  java
  • std::sort引发的core

      1. #include <stdio.h>
      2. #include <vector>
      3. #include <algorithm>
      4. #include <new>
      5. struct foo_t
      6. {
      7.     int size;
      8. };
      9. class cmp_t
      10. {
      11. public:
      12.     bool operator()(foo_t *a, foo_t *b)
      13.     {
      14.         return a->size >= b->size;
      15.     }
      16. };
      17. int main(int argc, char *argv[])
      18. {
      19.     std::vector<foo_t *> vec;
      20.     for (int i = 0; i < 17; i++)
      21.     {
      22.         foo_t *x = new(std::nothrow) foo_t();
      23.         if (NULL == x)
      24.         {
      25.             goto fail;
      26.         }
      27.         else
      28.         {
      29.             x->size = 1;
      30.         }
      31.         vec.push_back(x);
      32.     }
      33.     std::sort(vec.begin(), vec.end(), cmp_t());
      34. fail:
      35.     for(std::vector<foo_t *>::iterator iter = vec.begin(); vec.end() != iter; ++iter)
      36.     {
      37.         delete *iter;
      38.         *iter = NULL;
      39.     }
      40.     return 0;
      41. }
      42. 然后编译
        1. g++ main.cpp -Werror -Wall -g
        然后执行,此时系统出core,错误类型为段错误
        如果无core文件产生,可以使用
        1. ulimit -c unlimited
        后重新执行一次,此时就会有core文件生成
        然后
        1. gdb a.out core
        2. (gdb) bt
        3. #0  0x0804889e in cmp_t::operator() (this=0xbfed92d0, a=0x0, b=0x9a9d0c8) at main.cpp:16
          #1  0x080497ff in std::__unguarded_partition<__gnu_cxx::__normal_iterator<foo_t**, std::vector<foo_t*, std::allocator<foo_t*> > >, foo_t*, cmp_t> (__first=..., __last=..., __pivot=@0x9a9d1a0, __comp=...) at /usr/include/c++/4.6/bits/stl_algo.h:2233
          #2  0x0804926a in std::__unguarded_partition_pivot<__gnu_cxx::__normal_iterator<foo_t**, std::vector<foo_t*, std::allocator<foo_t*> > >, cmp_t> (__first=..., __last=..., __comp=...) at /usr/include/c++/4.6/bits/stl_algo.h:2265
          #3  0x08048e84 in std::__introsort_loop<__gnu_cxx::__normal_iterator<foo_t**, std::vector<foo_t*, std::allocator<foo_t*> > >, int, cmp_t> (
              __first=..., __last=..., __depth_limit=7, __comp=...) at /usr/include/c++/4.6/bits/stl_algo.h:2306
          #4  0x08048a22 in std::sort<__gnu_cxx::__normal_iterator<foo_t**, std::vector<foo_t*, std::allocator<foo_t*> > >, cmp_t> (__first=...,
              __last=..., __comp=...) at /usr/include/c++/4.6/bits/stl_algo.h:5368
          #5  0x080487ce in main (argc=1, argv=0xbfed9464) at main.cpp:38

        可以看到,系统core在了排序函数里面。
        然后通过分析stl代码发现以下一段代码
        1. /// This is a helper function...
        2.   template<typename _RandomAccessIterator, typename _Tp, typename _Compare>
        3.     _RandomAccessIterator
        4.     __unguarded_partition(_RandomAccessIterator __first,
        5.              _RandomAccessIterator __last,
        6.              const _Tp& __pivot, _Compare __comp)
        7.     {
        8.       while (true)
        9.     {
        10.      while (__comp(*__first, __pivot))
        11.      ++__first;
        12.      --__last;
        13.      while (__comp(__pivot, *__last))
        14.      --__last;
        15.      if (!(__first < __last))
        16.      return __first;
        17.      std::iter_swap(__first, __last);
        18.      ++__first;
        19.     }
        20.     }
        此函数完成快速排序中分区功能,即将比哨兵小的数据放在其前,大的放在其后。
        函数中使用的是
        while (__comp(*__first, __pivot))
            ++__first;

        如果当比较元素相同返回真时,此时比较元素将会继续向下遍历,在极端情况下,例如程序中所有元素都是一样的情况下,在这种情况下,就会出现访问越界,结果就是导致程序出现segment fault

        所以在写c++ stl中的比较函数是,bool返回真的时候,一定是“真的”大,或者小,等于的时候只能返回false。


  • 相关阅读:
    运算符重载
    C++ 画星号图形——圆形(核心代码记录)
    C++ 画星号图形——空心三角形(星号左对齐)(核心代码介绍)
    C++ 画星号图形——空心三角形(星号居中对齐)(核心代码介绍)
    QMap迭代器
    QVector也是隐式数据共享的
    调试dump文件
    How does the compilation and linking process work?
    when to use reinterpret_cast
    构造类的时候,提供类型转换
  • 原文地址:https://www.cnblogs.com/zhoug2020/p/4572051.html
Copyright © 2011-2022 走看看