2017-10-10 13 views
4

次のコードは、GCC 6.1.0でコンパイルしたときにセグメンテーション違反を生成します。不思議なことに、エラーは一貫していますが、サイズが小さい場合や比較式が少し異なる場合は発生しません。 あなたはどんな考えがありますか?GCCのstd :: sortとlambdaの間違った動作

#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

true IFF(場合にのみ)最初の引数(p1)さを返すコンパレータが必要std::sort() ...私は意味

(p1.second < p2.second) 

(p1.second <= p2.second) 

を変更してみてください厳密にはは第2のものより低い(p2)。つまり、p1p2に等しい場合は、falseを返す必要があります。

テストはp1p2に等しいときにもtrueを得る

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

ある場合。 p1p2に等しいとき、私は間違っていないよ場合の挙動は(もとセグメンテーションフォールト)ので、「不安定な動作」未定義です... trueを返すコンパレータと

は絶対に理解できます。

11

ここでの問題はを注文弱い厳しいを必要とする、あなたのラムダはCompareのための標準的な要件を満たしていないということです。

  • 厳しい!comp(x, x)は、すべてのx中のためtrueなければならないことを意味しますあなたの場合(x.first == x.first && x.second <= x.second)のxごとにcomp(x, x) == trueからカスタムコンパレータ(ラムダ)のケースではないシーケンスです。

あなたはp1.second < p2.secondp1.second <= p2.secondを変更、またはstd::pairのための標準的な比較演算子を使用する必要があり、次のいずれか

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

にlibstdC++はマクロ_GLIBCXX_DEBUGを定義することで有効にすることができdebug modeを持っています。

$ 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>; 
    } 
関連する問題