久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

std::sort引發(fā)的core

 mrjbydd 2012-06-05

這兩天定位了一個(gè)由std::sort引發(fā)的core,。


寫了下面的程序來復(fù)現(xiàn)此問題,。
  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. }
然后編譯
  1. g++ main.cpp -Werror -Wall -g
然后執(zhí)行,此時(shí)系統(tǒng)出core,錯(cuò)誤類型為段錯(cuò)誤
如果無core文件產(chǎn)生,,可以使用
  1. ulimit -c unlimited
后重新執(zhí)行一次,,此時(shí)就會(huì)有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

可以看到,,系統(tǒng)core在了排序函數(shù)里面,。
然后通過分析stl代碼發(fā)現(xiàn)以下一段代碼
  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.     }
此函數(shù)完成快速排序中分區(qū)功能,即將比哨兵小的數(shù)據(jù)放在其前,,大的放在其后,。
函數(shù)中使用的是
while (__comp(*__first, __pivot))
    ++__first;

如果當(dāng)比較元素相同返回真時(shí),此時(shí)比較元素將會(huì)繼續(xù)向下遍歷,在極端情況下,,例如程序中所有元素都是一樣的情況下,,在這種情況下,就會(huì)出現(xiàn)訪問越界,,結(jié)果就是導(dǎo)致程序出現(xiàn)segment fault

所以在寫c++ stl中的比較函數(shù)是,,bool返回真的時(shí)候,一定是“真的”大,,或者小,,等于的時(shí)候只能返回false。


這個(gè)錯(cuò)誤算是一次教訓(xùn),,索性的是沒有引起大范圍的錯(cuò)誤。

    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,,所有內(nèi)容均由用戶發(fā)布,,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式,、誘導(dǎo)購買等信息,,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,,請點(diǎn)擊一鍵舉報(bào),。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多