• #include <stdio.h>
  • #include <vector>
  • #include <algorithm>
  • #include <new>
  • struct foo_t
  • {
  •     int size;
  • };
  • class cmp_t
  • {
  • public:
  •     bool operator()(foo_t *a, foo_t *b)
  •     {
  •         return a->size >= b->size;
  •     }
  • };
  • int main(int argc, char *argv[])
  • {
  •     std::vector<foo_t *> vec;
  •     for (int i = 0; i < 17; i++)
  •     {
  •         foo_t *x = new(std::nothrow) foo_t();
  •         if (NULL == x)
  •         {
  •             goto fail;
  •         }
  •         else
  •         {
  •             x->size = 1;
  •         }
  •         vec.push_back(x);
  •     }
  •     std::sort(vec.begin(), vec.end(), cmp_t());
  • fail:
  •     for(std::vector<foo_t *>::iterator iter = vec.begin(); vec.end() != iter; ++iter)
  •     {
  •         delete *iter;
  •         *iter = NULL;
  •     }
  •     return 0;
  • }
  • 然后编译
  • g++ main.cpp -Werror -Wall -g
  • 然后执行,此时系统出core,错误类型为段错误
    如果无core文件产生,可以使用
  • ulimit -c unlimited
  • 后重新执行一次,此时就会有core文件生成
    然后
  • gdb a.out core
  • (gdb) bt
  • #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代码发现以下一段代码
  • /// This is a helper function...
  •   template<typename _RandomAccessIterator, typename _Tp, typename _Compare>
  •     _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;
  •     }
  •     }
  • 此函数完成快速排序中分区功能,即将比哨兵小的数据放在其前,大的放在其后。
    函数中使用的是
    while (__comp(*__first, __pivot))
        ++__first;

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

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


    相关文章:

    猜你喜欢
    相关资源
    相似解决方案
    热门标签