7
votes

Pourquoi STD :: Trier trit un défaut de segmentation sur ce code?

Quelqu'un peut-il expliquer pourquoi le tri ci-dessous provoque des défauts SEG? Est-ce un bug connu avec g ++ (tri de vecteur de pointeurs)? Je compose de compiler avec g ++ 4.5.2.

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;
}


9 commentaires

Votre fonction de comparaison est fausse. Ce n'est pas la comparaison des valeurs mais juste des pointeurs - au mieux.


Il est simplifié de rendre le code plus court. Cela crée toujours une faute SEG.


Vous comparez des pointeurs de vecteur , la comparaison doit être effectuée sur les données


Ensuite, supprimez simplement la fonction de comparaison. Juste mettre ... là ou quelque chose; Il est distrayant de voir un code clairement brisé quand ce n'est pas le problème réel.


Alors, quelle est la fonction de comparaison réelle? En raison de la modifier à quelque chose de sensible fixe la faute SEG. ideone.com/qaaoa


Votre fonction comparateur est ce qui enfreint votre code. (ou son utilisation par STD :: Trier, peu importe).


Vous envisagez de vous structure de vecteur en tant que tableau 2D.. Voulez-vous trier chaque ligne de celui-ci?


Il n'y a aucun problème à trier un vecteur de pointeurs; Le problème consiste à utiliser non-égal au lieu de moins que dans la fonction de comparaison.


@ARUNMU: Il n'y a aucun problème associé à l'utilisation des pointeurs dans les comparaisons (il peut ne pas avoir de sens dans ce contexte, mais cela ne la causera pas de crash (et cela est potentiellement utile dans d'autres contextes)). Ainsi, le phrasé «doit être fait sur les données» n'est pas justifié.


5 Réponses :


9
votes

Troisième argument de std :: Trier doit être une fonction (ou un objet fonctionnel) tel que si comparer (A, B) est vrai Alors comparer (b, a) doit être false , mais celui-ci n'est pas tel. Donc, votre programme est UB et peut donner tout résultat.


1 commentaires

Tout vrai. Mais ne répond toujours pas vraiment à la question. Vous devez expliquer la relation qui doit être définie par l'opérateur de comparaison.



16
votes

La fonction de comparaison doit définir une commande faible stricte qui signifie que A et B ne peut pas être à la fois true. Votre fonction de comparaison n'a pas cette propriété.

Il ne définit aucune relation "avant-après", il n'est donc pas étonnant que l'algorithme s'appuie sur cette propriété ne fonctionne pas correctement.


0 commentaires

9
votes

Aucun code n'est faux. Les fonctions de comparaison pour STD :: Trier doivent utiliser xxx


5 commentaires

Les deux autres réponses l'indiquent mieux, un ordre faible strict est ce que je voulais vraiment dire :)


Bien sûr, vous pouvez comparer les vecteurs avec <, voir ici Cplusplus.com/reference/stl/ Vector / opérateurs . Veuillez supprimer vos votes en panne. Ma réponse n'est pas aussi bonne que les autres, mais ce n'est pas incorrect.


@Arunmu Oui, vous pouvez comparer des vecteurs comme ça.


L'opérateur de comparaison fait pas besoin d'utiliser '<' il pourrait aussi facilement utiliser «>» ou une foule d'autres comparaisons. C'est une réponse faible parce que vous ne définissez pas ce que la relation de l'opérateur de comparaison doit définir.


@Martin: Oui, c'est le point que j'ai adressé dans mon premier commentaire. Cependant, ma réponse inclut certains code afin que cela puisse être utile à l'OP.



1
votes

Définissez votre fonction de comparaison sous la forme

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


2 commentaires

Vous devriez demander à cela.


La fonction de comparaison initiale indiquée par les valeurs OP comparées (elle vient d'optimiser la même comparaison d'objet ...)



2
votes

Assurez-vous que vous utilisez juste supérieur ou inférieur à. ne pas utiliser fort> égal à. Égal à Segfault avec certains ensembles de données:

// Good
bool face_cmp(const A *x, const A *y) {
  return *x < *y;
}

// Also okay for reverse sorting
bool face_cmp(const A *x, const A *y) {
  return *x > *y;
}

// This will SEGFAULT
bool face_cmp(const A *x, const A *y) {
  return *x <= *y;
}


0 commentaires