轉載地址:http://blog.chinaunix.net/u2/61062/showart_2150555.html
註:今天使用std::sort函數出了一個錯誤,錯誤圖片如下:
在網上搜到一篇解決這個錯誤的有用的資料,特記錄。
1.例子
先舉個例子:分析一下程式的運行結果:看看在三種情況下程式的輸出分別是什麼,有可能出現異常
////////////////////////////////////////////////////
#pragma once
#include <vector>
#include <algorithm>
///////////////////////////////////////////////////
/// 下面是三個自訂的謂詞函數,排序演算法將分別使用這三個函數
//////////////////////////////////////////////////
bool compare(int a,int b)
{
return a - b;
}
bool compare1(int a,int b)
{
return a < b;
}
bool compare2(int a,int b)
{
return a <= b;
}
/////////////////////////////////////////////////////
///Main 函數
////////////////////////////////////////////////////
int main(int arg,char * argv[])
{
std::vector<int> vec;
vec.push_back(7);
vec.push_back(5);
vec.push_back(8);
vec.push_back(10);
vec.push_back(48);
vec.push_back(32);
vec.push_back(7);
vec.push_back(5);
vec.push_back(3);
vec.push_back(3);
//第一種情況
std::sort(vec.begin(),vec.end(),compare);
//第二種情況
std::sort(vec.begin(),vec.end(),compare1);
//第三種情況
std::sort(vec.begin(),vec.end(),compare2);
getchar();
return 0;
}
//////////////////////////////////////////////////
2.結果
三種情況在程式中分別使用後(這裡為了節省空間的寫在了一起)的結果是:
(1)第一種情況(compare函數)和第三種情況(compare2 函數)出現錯誤(assert):
(2)第二種情況(compare1函數)下程式運行正常,結果正確。
3.分析
第一種情況和第三種情況出錯的原因是:跟蹤到出現異常的stl的原始碼的一個函數中,就是下面這個函數:
template<class _Pr, class _Ty1, class _Ty2> inline
bool __CLRCALL_OR_CDECL _Debug_lt_pred(_Pr _Pred, _Ty1& _Left, _Ty2& _Right,
const wchar_t *_Where, unsigned int _Line)
{ // test if _Pred(_Left, _Right) and _Pred is strict weak ordering
if (!_Pred (_Left, _Right))
return (false);
else if (_Pred(_Right, _Left))
_DEBUG_ERROR2("invalid operator<", _Where, _Line);
return (true);
}
這個函數要求對於調用的兩個參數交換位置時不能得到相同的true的結果。也就是為什麼第一種和第三種不行的原因了:A當待比較的兩個值相等的時候,第三種情況和B當待比較的兩個值不相等的時候,第一種情況。
但是對於調用的兩個參數交換位置時允許得到相同的false的結果,因為這時根本不進行兩個參數交換位置操作!!(具體看程式:在第一個if的時候就返回false了)