std::sort引发的core(这个分析还是很不错的!!!)

    xiaoxiao2025-02-13  9

            转载地址:http://blog.chinaunix.net/uid-23146151-id-3066266.html

     

            这两天定位了一个由std::sort引发的core。

    写了下面的程序来复现此问题。 #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 *= 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*, 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 > >, 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 > >, 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 > >, 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。 这个错误算是一次教训,所幸的是没有引起大范围的错误。

     

    涛歌依旧 认证博客专家 排名第一 点链接学人工智能 公众号免费领资料 ❤️零基础入门进阶人工智能 ❤️欢迎关注涛哥公众号,免费领海量学习资料。涛哥:毕业后就职于华为和腾讯。微信:ai_taogeyijiu
    转载请注明原文地址: https://ju.6miu.com/read-1296404.html
    最新回复(0)