2013-05-14 58 views
4

我有一個容器存儲指針。我試圖根據指針指向的相應對象中的數據成員以非遞增順序對這些指針進行排序。就我而言,很可能有很多對象對該數據成員具有相同的值。標準::排序與相同的元素給出分割錯誤

以下是說明問題的簡短代碼。對排序功能的調用會導致分段錯誤。奇怪的是,如果容器中有16個元素指向具有相同值的對象,則排序似乎有效。但是如果我有17個元素指向具有相同值的對象,它會給出一個seg故障。

任何人都可以請解釋爲什麼發生這種情況?

#include <iostream> 
#include <algorithm> 
#include <deque> 

//some class 
class A { 
public: 
    double a; 
    A(double aval); 
}; 

A::A(double aval) : a(aval) {} 

//compare class 
struct cmp_A : std::greater_equal<A*> { 
    bool operator() (const A* x, const A* y) const; 
} cmp_A_obj; 

//greater_equal comparison 
bool cmp_A::operator() (const A* x, const A* y) const { 
    return (x->a >= y->a); 
} 

int main() { 
    std::deque<A*> Adeque; 
    //insert 17 A pointers into the container 
    for(int i = 1; i<=17; i++) { 
     Adeque.push_back(new A(5)); 
    } 

    //This call to sort gives a Segmentation fault 
    std::sort(Adeque.begin(), Adeque.end(), cmp_A_obj); 

    for(std::deque<A*>::iterator i = Adeque.begin(); i!= Adeque.end(); i++) { 
     std::cout << "|" << (*i)->a; 
    } 
    std::cout << std::endl; 
} 

回答

14

您的比較必須實行strict weak ordering。小於或等於不滿足此。它應該等於「小於」或「大於」,如在運算符<>中實現的,例如整數。元素

平等是通過兩次運用這個順序確定:

(!cmp(a,b)) && (!cmp(b,a)); // if this is false, a == b 
+0

你或許應該改變「小於或大於」到「''<' or '>」不那麼曖昧。 (小於或大於可以被解釋爲'!=') – Pubby 2013-05-14 05:45:01

+1

@Pubby我改述了答案的這一部分。我擔心我的答案意味着必須超載'<' or '>'。 – juanchopanza 2013-05-14 05:47:33

+1

+10這對於一個不小心的人來說是一個巨大的陷阱。我自己已經被這個錯誤所困擾,並且造成這個問題的原因並不明顯。恕我直言,它需要更好地記錄在所有的STL參考。 – gavinb 2013-05-14 05:48:00