2017-10-10 92 views
4

以下代碼在使用GCC 6.1.0進行編譯時會生成分段錯誤。奇怪的是,錯誤是一致的,但不會發生較小的尺寸或略有不同的比較表達式。 你們有什麼想法,爲什麼?GCC std :: sort與lambdas的錯誤行爲

#include <vector> 
#include <algorithm> 
#include <iostream> 
int main() { 
    int n = 1000; 
    std::vector<std::pair<double, double>> vec; 
    for(int i = 0; i < n; i++) { 
     vec.push_back(std::make_pair<double, double>((7*i)%3, (3*i)%5)); 
    } 
    std::sort(vec.begin(), vec.end(), [](std::pair<double, double> const & p1, std::pair<double, double> const & p2) {return (p1.first < p2.first) || ((p1.first==p2.first)&& (p1.second <= p2.second));}); 
    return 0; 
} 
+0

你應該知道,如果你想要的只是一個詞法對比,那麼'std :: pair'已經做到了,不需要你的干預。 – StoryTeller

+0

@StoryTeller感謝您的提示。但是現在真正困擾我的是分段故障的來源! –

+5

來源在你的比較中,不會產生正確的順序關係。該代碼具有未定義的行爲。 – StoryTeller

回答

13

嘗試改變

(p1.second <= p2.second) 

(p1.second < p2.second) 

我的意思是...... std::sort()需要返回true當且僅當(當且僅當)的第一個參數比較(p1)是嚴格低於第二個(p2)。即:當p1等於p2時,必須返回false

如果測試是

(p1.first < p2.first) 
|| ((p1.first==p2.first)&& (p1.second <= p2.second)) 

你獲得true也當p1等於p2

有返回truep1等於p2 ......如果我沒看錯的行爲是不確定的比較等等的「錯誤行爲」(和分段錯誤也)是完全可以理解的。

11

這裏的問題是,你的拉姆達不符合標準要求Compare,這需要一個嚴格弱排序

  • 嚴格意味着!comp(x, x)必須true爲每x在(x.first == x.first && x.second <= x.second)中每xcomp(x, x) == true自定義比較器(lambda)的情況並非如此。

你應該要麼改變p1.second <= p2.secondp1.second < p2.second,或使用標準的比較運算符std::pair

std::sort(vec.begin(), vec.end()); 
2

的libstdC++有一個debug mode可以通過定義宏_GLIBCXX_DEBUG啓用。

$ g++-6 b.cc -D_GLIBCXX_DEBUG && ./a.out 
/usr/include/c++/6/bits/stl_algo.h:4737: 
Error: comparison doesn't meet irreflexive requirements, assert(!(a < a)). 

Objects involved in the operation: 
    instance "functor" @ 0x0x7ffe48ba5a20 { 
     type = main::{lambda(std::pair<double, double> const&, std::pair<double, double> const&)#1}; 
    } 
    iterator::value_type "ordered type" { 
     type = std::pair<double, double>; 
    }