2011-08-08 68 views
4

有人可以解釋爲什麼以下種類會導致seg故障嗎?這是一個已知的bug與g ++(排序指針向量)?我正在用g ++ 4.5.2編譯。爲什麼std :: sort在這段代碼上拋出一個分段錯誤?

#include <iostream> 
#include <algorithm> 
#include <vector> 

using namespace std; 

typedef vector<int> A; 
bool face_cmp(const A *x, const A *y) { 
    return x != y; 
} 

int main(int argc, char* argv[]) { 

    vector<A *> vec; 
    for (int i=0; i<100; i++) { 
    vec.push_back(new vector<int>(i%100, i*i)); 
    } 

    vector<A *>::iterator it; 
    sort(vec.begin(), vec.end(), face_cmp); 

    return EXIT_SUCCESS; 
} 

編譯鍵盤上提供了:

/usr/local/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../../include/c++/4.1.2/debug/safe_iterator.h:240: 
    error: attempt to decrement a dereferenceable (start-of-sequence)  
    iterator. 

Objects involved in the operation: 
iterator "this" @ 0x0xbf4b0844 { 
type = N11__gnu_debug14_Safe_iteratorIN9__gnu_cxx17__normal_iteratorIPPN15__gnu_debug_def6vectorIiSaIiEEEN10__gnu_norm6vectorIS7_SaIS7_EEEEENS4_IS7_SB_EEEE (mutable iterator); 
    state = dereferenceable (start-of-sequence); 
    references sequence with type `N15__gnu_debug_def6vectorIPNS0_IiSaIiEEESaIS3_EEE' @ 0x0xbf4b0844 
} 

謝謝你的所有的快速回復。原始的功能是:

if (x == y) return false; 
if (x->size() < y->size()) return true; 
else if (x->size() > y->size()) return false; 
else { 
    for (register int i=0; i<x->size(); i++) { 
    if ((*x)[i] < (*y)[i]) return true; 
    } 
    return false; 
} 

我剛剛改變了第一行,並刪除了其餘的。但事實證明,它也遭受不嚴格的弱排序(如果(* x)[i]>(* y)[i]我忘記了這種情況)。我應該先發布整個功能。儘管如此,再次感謝!

+1

你比較函數是僞造的。它不是比較價值觀,而是最好的指標。 –

+0

簡化代碼以縮短代碼長度。它仍然會創建一個seg故障。 –

+0

您正在比較矢量的指針,必須對數據進行比較 – Arunmu

回答

8

std::sort第三參數應該是一個函數(或功能對象),使得如果compare(a, b)true然後compare(b, a)false,但你的一個不是這樣。所以你的程序是UB並且可以給出任何結果。

+0

全部爲真。但仍然沒有真正回答這個問題。您需要解釋實際需要由比較運算符定義的關係。 –

12

比較函數必須定義嚴格的弱排序,這意味着a < bb < a不能同時爲真。你的比較函數沒有這個屬性。

它沒有定義任何「前後」關係,所以難怪依賴此屬性的算法無法正常工作。

7

不,你的代碼是錯誤的。 std :: sort的比較函數必須使用<或者它是等價的,使用!=是不正確的。也許你想要這個

bool face_cmp(const A *x, const A *y) { 
    return *x < *y; 
} 
+0

另外兩個答案說明它更好,嚴格的弱排序是我真正想說的:) – john

+2

當然,你可以將載體與<,參見http://www.cplusplus.com/reference/stl/vector/operators /。請刪除您的倒票。我的回答不如其他人好,但這並不正確。 – john

+0

@ArunMu是的,你可以比較這樣的載體。 –

1

定義你的比較功能

bool face_cmp(const A *x, const A *y) { 
    return x < y; 
} 
+0

你確定要比較地址(指針)嗎? –

+0

你應該詢問OP。 – zvrba

+0

OP顯示的原始比較函數比較值(它只是優化了相同的對象比較...) –

相關問題