IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Langage C++ Discussion :

bug étrange en fin de fonction


Sujet :

Langage C++

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Inscrit en
    Juillet 2009
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 35
    Par défaut bug étrange en fin de fonction
    Bonjour à tous!

    Désolé pour le titre peu explicite, mais mon problème est assez compliqué à expliquer...

    Je travaille sur un solveur de nonogramme (un jeu à résolution binaire).

    Mon programme compile mais ne tourne pas. J'ai donc cherché d'où vient l'erreur en ajoutant des cout un peu partout. et j'ai identifé que l'erreur arrivait à la fin d'un fonction :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    void solve() {
        algo1();
        cout<<"fin solve"<<endl;
    }
     
    void algo1() {
        ...instructions...
        cout<<"fin algo"<<endl;
    }
    http://pastie.org/1300872 pour un peu plus de code.

    à la sortie, je n'ai que "fin algo2" qui s'affiche. je ne comprends vraiment pas d'où cela peut venir. j'ai déjà vérifié les potentiels ; et } manquants. je ne sais plus trop quoi faire... des idées?

    merci

    EDIT
    J'ai testé de déporter la fin du code (lignes 46 à 92 dans pastie) de ma fonction algo1() dans une autre fonction, et mon problème s'exporte dans la fonction nouvellement créée. ça ne m'avance pas, mais peut-être que ça vous avancera ^^

    EDIT 2
    J'ai testé de faire renvoyer une valeur à mes fonctions, de cette manière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    void solve() {
        cout << algo1() << endl;
        cout<<"fin solve"<<endl;
    }
     
    int algo1() {
        ...instructions...
        cout<<"fin algo"<<endl;
        return 1;
    }
    le 1 renvoyé par algo1 et le endl sont affichés en console. c'est de plus en plus énigmatique à mes yeux



    EDIT 3 (vous inquietez pas, je dors comme tout le monde, mais je vis à taïwan, c'est le jour ici)
    J'ai reconstruit mon projet avec Code Blocks, pour profiter de son debugger. L'erreur renvoyée quand ça plante est une segmentation fault. Je vois pas trop d'où ça peut venir...

  2. #2
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Mon proxy entreprise m'empêche d'aller voir ton code

    Peut être un écrasement de variable locale (sur la pile donc) qui met la pagaille dans la call stack.

    Montre ton code (ligne 46 à 92) puisque tu arrives à reproduire.
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  3. #3
    Responsable 2D/3D/Jeux


    Avatar de LittleWhite
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Mai 2008
    Messages
    27 119
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur développement logiciels

    Informations forums :
    Inscription : Mai 2008
    Messages : 27 119
    Billets dans le blog
    148
    Par défaut
    Bonjour,

    Citation Envoyé par cycloop Voir le message
    j'ai déjà vérifié les potentiels ; et } manquants. je ne sais plus trop quoi faire... des idées?
    Cela aurait été une erreur de compilation (erreur syntaxique) et non une erreur de segmentation.
    Une erreur de segmentation, est une erreur produite lorsque le CPU se rend compte que l'on fait quelque de très invalide .
    Par exemple:
    - Utilisation d'un pointeur qui ne pointe pas sur l'objet voulu (pointeur invalide -> Soit NULL, soit déjà libéré ... soit jamais alloué)
    - Accès en dehors des limites de nos tableaux (ce que je soupçonne dans votre code)

    Pour trouver rapidement ces erreurs, l'utilisation du debuggueur est primordiale. Déjà celui ci, lorsqu'on lance le programme en mode debug, va s'arrêter sur la ligne qui caue l'erreur. Et en plus, il nous donnes les valeurs des variabls (ce qui facilite le repérage des accès hors des limites des tableaux).

    En dernier conseil, je vais dire que vous devriez donner une valeur à chaque variable que vous déclarer.
    Par exemple:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
    int i = 0;
    // Au lieu de juste
    int i;
    Vous souhaitez participer à la rubrique 2D/3D/Jeux ? Contactez-moi

    Ma page sur DVP
    Mon Portfolio

    Qui connaît l'erreur, connaît la solution.

  4. #4
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Bonjour,

    Je vois beaucoup d'accès aux éléments du vecteur « tempRow » via leur indice, mais aucune vérification que ce dernier est valide.
    Je me joins donc à LittleWhite pour pointer du doigt cette possibilité d'erreur.
    Bon, tu es peut-être sûr de ne jamais aller chercher un élément hors du vecteur, mais une couche supplémentaire de vérification n'a jamais fait de mal à personne.

    L'opérateur « [] » est pratique et rapide, mais ne teste pas la validité de l'indice fourni.
    Essaie la fonction membre « at » ; si tu as une autre chose qu'une erreur de segmentation, c'est qu'à un moment ou un autre tu tentes d'accéder à un élément hors du vecteur.

  5. #5
    Membre émérite Avatar de Steph_ng8
    Homme Profil pro
    Doctorant en Informatique
    Inscrit en
    Septembre 2010
    Messages
    677
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Doctorant en Informatique

    Informations forums :
    Inscription : Septembre 2010
    Messages : 677
    Par défaut
    Si je puis me permettre, j'aimerais faire quelques petites remarques…

    Pour parcourir les éléments d'un conteneur, vive les itérateurs !
    Bon, si on a absolument besoin des indices numériques…

    Utiliser une fonction directement dans la condition d'arrêt d'une boucle, ça revient à l'appeler plusieurs fois, une par itération.
    Si elle retourne toujours la même valeur, quelle que soit l'itération, pourquoi ne pas stocker cette valeur dans une variable, et alors n'appeler la fonction qu'une seule fois ?

    C'est vraiment nécessaire d'avoir deux vecteurs de Cell ?
    J'ai l'impression que tu n'as jamais besoin des deux en même temps…

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    for (idCell = 0; idCell < finalRow.size(); idCell++)
        tempRow.push_back(finalRow[idCell]);
    Il y a des manières plus élégantes de copier le contenu d'un vecteur dans un autre…
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    for (vector<Cell>::iterator it = finalRow.begin(), end = finalRow.end(); it != end; ++it)
        tempRow.push_back(*it);
     
    //**************************************//
     
    #include <algorithm>      // pour std::copy
    #include <iterator>       // pour std::back_insterter
     
    std::copy(finalRow.begin(), finalRow.end(), std::back_inserter(tempRow));
     
    //**************************************//
     
    tempRow = finalRow;
    Bon, j'ai mis la dernière parce que « tempRow » me semble vide au moment de la copie.

    Bonne continuation !

  6. #6
    Membre averti
    Inscrit en
    Juillet 2009
    Messages
    35
    Détails du profil
    Informations forums :
    Inscription : Juillet 2009
    Messages : 35
    Par défaut
    le code entre les lignes 46 et 92, pour ram-0000 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
                i=0; // will grow to row size
                for(idValue=0;idValue<m_clues[idClue].values.size();idValue++) {
    cout<<"c"<<endl;
     
                    //MANAGE WHITE CELLS
     
                    enoughSpace=false;
     
                    while(!enoughSpace){
     
                        while(tempRow[i].color == WHITE) i++; // skip white cells (case |XXXXX? )
     
                        // check space
                        enoughSpace=true;
                        for(j=0;j<m_clues[idClue].values[idValue];j++) { 
                            if(tempRow[i+j].color==WHITE) {
                                enoughSpace=false;
                                break;
                            }
                        }
                        if(!enoughSpace) { 
                            // fill with white until the white cell
                            while(tempRow[i].color==UNKNOWN) {
                                tempRow[i].color=WHITE;
                                i++;
                            }
                            i++; // place iterator on the first non-white cell
                        }
                    }//while !enoughSpace
     
                    //MANAGE BLACK CELLS
                    //if a black cell prevent temprow[i]
                    while(tempRow[i+m_clues[idClue].values[idValue]].color==BLACK) {
                        tempRow[i].color=WHITE;
                        i++;
                    }
     
                    //FILL CELLS
                    for(idCell=i;idCell<i+m_clues[idClue].values[idValue];idCell++) {
                        tempRow[idCell].color=BLACK;
                        tempRow[idCell].id_value=idValue;
                    }
                    i+=idCell;
     
                    tempRow[i].color=WHITE;
    cout<<"x"<<endl;
                }


    Citation Envoyé par ram-0000
    Peut être un écrasement de variable locale (sur la pile donc) qui met la pagaille dans la call stack.
    Code Block me parle effectivement de call stack quand il me pointe l'erreur. Je pense que le problème vient de là. Mais je ne vois pas comment ça peut se produire. La fonction ne prend rien en paramètre et ne renvoie rien...

    Citation Envoyé par LittleWhite
    - Accès en dehors des limites de nos tableaux (ce que je soupçonne dans votre code)
    ...
    En dernier conseil, je vais dire que vous devriez donner une valeur à chaque variable que vous déclarer.
    Citation Envoyé par Steph_ng8
    Bonjour,

    Je vois beaucoup d'accès aux éléments du vecteur « tempRow » via leur indice, mais aucune vérification que ce dernier est valide.
    Je me joins donc à LittleWhite pour pointer du doigt cette possibilité d'erreur.
    Bon, tu es peut-être sûr de ne jamais aller chercher un élément hors du vecteur, mais une couche supplémentaire de vérification n'a jamais fait de mal à personne.

    L'opérateur « [] » est pratique et rapide, mais ne teste pas la validité de l'indice fourni.
    Essaie la fonction membre « at » ; si tu as une autre chose qu'une erreur de segmentation, c'est qu'à un moment ou un autre tu tentes d'accéder à un élément hors du vecteur.
    J'ai ajouté les vérifications d'indice dans les boucles while et je suis en train de remplacer les boucles for avec les itérateurs. ça devrait résoudre tout problème de ce côté là. Le problème à tout modifier, c'est qu'on crée de nouvelles erreurs, donc là je débug ces petites erreurs pour pouvoir traiter la grosse

    Concernant les initialisations, j'ai pris l'habitude d'initialiser les variables au moment de les utiliser. ça permet de s'assurer qu'elle a la valeur qu'on veut. après, c'est vrai que ça ne coûte pas grand chose d'initialiser à 0 au début.

    Citation Envoyé par Steph_ng8 Voir le message
    Utiliser une fonction directement dans la condition d'arrêt d'une boucle, ça revient à l'appeler plusieurs fois, une par itération.
    Si elle retourne toujours la même valeur, quelle que soit l'itération, pourquoi ne pas stocker cette valeur dans une variable, et alors n'appeler la fonction qu'une seule fois ?

    C'est vraiment nécessaire d'avoir deux vecteurs de Cell ?
    J'ai l'impression que tu n'as jamais besoin des deux en même temps…
    Effectivement, stocker la valeur pourrait améliorer un peu les performances. Mais j'ai la mauvaise habitude de jeter un premier brouillon de code avant d'avoir réfléchi à ces questions.

    A propos des vecteurs : en fait ma fonction n'est pas encore terminée. dans la suite de mon algo, je vais être amené à ré-utiliser le vecteur qui n'a pas subi de traitement. donc pour le moment, c'est effectivement inutile, mais ça ne durera pas.


    Merci pour votre aide, je vous tiendrai informé quand j'aurai un peu plus avancé.

    EDIT
    Bon après avoir mis un beau code tout propre en suivant vos conseils, et après avoir débuggé ce code, tout marche nickel!

    merci à vous tous

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Erreur : valeur de retour en fin de fonction
    Par l1xnoir dans le forum Windows Forms
    Réponses: 3
    Dernier message: 19/04/2007, 16h32
  2. Bug étrange sur du single
    Par rodymary dans le forum VB 6 et antérieur
    Réponses: 15
    Dernier message: 31/08/2006, 15h52
  3. Réponses: 4
    Dernier message: 12/06/2006, 15h43
  4. Bug étrange
    Par xavier faure dans le forum Langage
    Réponses: 4
    Dernier message: 01/04/2006, 13h54
  5. [VB6]Bug étrange lié à l'horloge...
    Par méphistopheles dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 16/02/2006, 15h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo