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

 C++ Discussion :

Probleme segmentation fault


Sujet :

C++

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France, Somme (Picardie)

    Informations forums :
    Inscription : Mai 2008
    Messages : 217
    Points : 71
    Points
    71
    Par défaut Probleme segmentation fault
    Bonjour,

    J'ai un petit soucis et je suis nul en c++. Voilà j'ai compilé via un makefile mes sources mais quand j'exécute mon exe il me met Memery fault alors j'ai été voir dans le fichier coré et voici ce qu'il me met :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Program terminated with signal 11, Segmentation fault.
    #0  0x08050ee0 in CRequeteListe::Supprimer (this=0x8154600, pCr=0xfeff748c) at /devl/sap1/unix/src/pssess.pc:108
    108         for( ; pCrl->Suivant; pCrl=pCrl->Suivant)
    L'erreur vient de cette fonction :
    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
    /* Suppression d'une requete dans la chaine */
    CRequeteListe *CRequeteListe::Supprimer( CRequeteSql *pCr)
    {
        CRequeteListe *pCrl= this;
        CRequeteListe *pSuivant;
        if( pCrl->Element==pCr)
            {
            pSuivant = Suivant ;
            Suivant = NULL; 
            delete pCrl;
            return pSuivant;
            }   
        for( ; pCrl->Suivant; pCrl=pCrl->Suivant)
            if( pCrl->Suivant->Element == pCr)
                {
                pSuivant = pCrl->Suivant->Suivant; 
                pCrl->Suivant->Suivant = NULL; 
                delete pCrl->Suivant;
                pCrl->Suivant = pSuivant;
                }   
        return this;
    }
    Quelqu'un aurait une idée pourquoi çà tombe en erreur

    Merci d'avance

  2. #2
    Membre émérite
    Profil pro
    Inscrit en
    Novembre 2004
    Messages
    2 764
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2004
    Messages : 2 764
    Points : 2 705
    Points
    2 705
    Par défaut
    Ça me paraît louche, l'instruction Tu supprimes l'instance dans laquelle tu te trouves ?

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France, Somme (Picardie)

    Informations forums :
    Inscription : Mai 2008
    Messages : 217
    Points : 71
    Points
    71
    Par défaut
    Je ne sais pas trop, le programme n'a pas été fait par moi. Je recompile juste l'exe parce q'il y a eu migration de la version d'Oracle.

    Je ne sais pa si c'est çà qui plante mais l'erreur indiqué par le fichier core se trouve sur la boucle.

    Je suis un peu perdu avec tout ces pointeur...

  4. #4
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    A ton avis, que ce passe-t-il lorsque l'élément recherché est le dernier de ta liste chaînée?

  5. #5
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France, Somme (Picardie)

    Informations forums :
    Inscription : Mai 2008
    Messages : 217
    Points : 71
    Points
    71
    Par défaut
    heu bonne question

    Je ne sais pas trop, j'arrive souvent à comprendre une fonction mais là c'est un peu flou, je ne vois pas trop, je suppose qu'il y a un soucis si c'est le dernier element de la liste qui recherché, au niveau de la boucle surment, quand il arrive au dernier element il plante car li ne sait pas quelle est l'element suivant.

    Je suis sur la bonne voie ou pas du tout, je comprend pas grand chose à cette fonction...

  6. #6
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Effectivement, c'est la bonne voie.
    Dans la boucle for, l'incrément est fait avant le test (sauf, bien sûr en entrée de boucle).
    Donc, si on décortique:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
       for( ; pCrl->Suivant; pCrl=pCrl->Suivant)
            if( pCrl->Suivant->Element == pCr)
                {
                pSuivant = pCrl->Suivant->Suivant; 
                pCrl->Suivant->Suivant = NULL; 
                delete pCrl->Suivant;
                pCrl->Suivant = pSuivant;
                }
    Supposons que le dernier élément est celui recherché.
    Donc pCrl pointe sur l'avant dernier élément.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    if( pCrl->Suivant->Element == pCrl)
    est vérifié donc on rentre:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pSuivant = pCrl->Suivant->Suivant;
    Là tu récupères le suivant du suivant, donc le suivant du dernier, donc il y a de forte chance que ce soit NULL.
    Les deux lignes suivantes déchaînent l'élément et le suppriment.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    pCrl->Suivant = pSuivant;
    l'élément courant (pCrl) est renchaîné avec NULL.
    Retour dans ta boucle: . Donc pCrl vaut NULL.
    Test: Déréférencement de NULL, et là boum

    Tu auras aussi un problème si deux éléments identiques se suivent. Seul le premier sera déchaîné.

    En fait, la boucle est bancale car lorsqu'elle trouve un élément à déchaîner, elle avance d'un pas ce qui fait que l'élément suivant celui qui est déchaîné n'est pas pris en compte.

    Autre chose me parait étrange: si l'élément recherché est le premier, on le supprime et on retourne l'élément suivant. Si par contre l'élément n'est pas le premier, alors on parcours toute la liste pour essayer d'enlever toutes les occurrences de l'éléments recherchés. Quelque chose cloche. Soit la boucle est faite pour enlever le premier élément correspondant à celui fourni en argument, soit pour enlever toutes ses occurrences.

  7. #7
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France, Somme (Picardie)

    Informations forums :
    Inscription : Mai 2008
    Messages : 217
    Points : 71
    Points
    71
    Par défaut
    Merci pour ton explication.

    En fait, la boucle est bancale car lorsqu'elle trouve un élément à déchaîner, elle avance d'un pas ce qui fait que l'élément suivant celui qui est déchaîné n'est pas pris en compte.
    Que dois-je faire pour que la boucle fonctionne mieux. Bizarrement, le programme fonctionnait avant qu'il soit migré...

    Autre chose me parait étrange: si l'élément recherché est le premier, on le supprime et on retourne l'élément suivant. Si par contre l'élément n'est pas le premier, alors on parcours toute la liste pour essayer d'enlever toutes les occurrences de l'éléments recherchés. Quelque chose cloche. Soit la boucle est faite pour enlever le premier élément correspondant à celui fourni en argument, soit pour enlever toutes ses occurrences.
    Alors là bonne question, je pense que c'est supprimer juste le premiere élément puisque si on s'appuie sur le commentaire de la fonction, c'est "Suppression d'une requete dans la chaine"

  8. #8
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    En fonction du temps que tu as et de ce que veux faire ta fonction:
    1/ Remplacer les listes maisons par des std::
    2/ ou Réecrire la boucle en ayant deux pointeurs: un sur l'élément courant, un sur le précédent. L'incrément se fait sur le précédent et le 'déchaînage' sur le courant.
    3/ ou
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     for( ; pCrl->Suivant; pCrl=pCrl->Suivant)
            if( pCrl->Suivant->Element == pCr)
                {
                pSuivant = pCrl->Suivant->Suivant; 
                pCrl->Suivant->Suivant = NULL; 
                delete pCrl->Suivant;
                pCrl->Suivant = pSuivant;
                return this;
                }
    Là ça implique que seul le premier élément trouvé sera supprimé.

  9. #9
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France, Somme (Picardie)

    Informations forums :
    Inscription : Mai 2008
    Messages : 217
    Points : 71
    Points
    71
    Par défaut
    Merci pour tes réponses,

    J'ai essayé la proposition 3, elle ne fonctionne pas, çà me fait un abort.

    Comment fais-tu pour la proposition 1.

    Par contre pour la 2, j'ai compris ce qu'il fallait faire mais je ne sais pas comment pas...

    Pourrais-tu m'aider stp

    Merci,

  10. #10
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Citation Envoyé par miketidy Voir le message
    Merci pour tes réponses,
    De rien

    Citation Envoyé par miketidy Voir le message
    J'ai essayé la proposition 3, elle ne fonctionne pas, çà me fait un abort.
    Toujours au même endroit? Il y a peu être autre chose.

    Citation Envoyé par miketidy Voir le message
    Comment fais-tu pour la proposition 1.
    Regarde du côte de std::vector ou std::list. Mais, ca va impliquer probablement de modifier beaucoup de code. Donc, ton client/boss préfère que tu avances vite ou que tu fiabilise le soft?

    Citation Envoyé par miketidy Voir le message
    Par contre pour la 2, j'ai compris ce qu'il fallait faire mais je ne sais pas comment pas...
    Pour faire ton algo, tu prend une feuille papier et tu dessines ta liste sous forme de [premier]->[second]->[troisième]...
    Ensuite, tu regarde comment positionner tes itérateurs pour savoir comment les faire avancer etc...
    Plutôt qu'une boucle for, moi, je préfère une boucle while. Tu as deux itérateurs: un courant, un sur le précédent. Tu avances tant que ton courant est valide et qu'il n'est pas égale à ta valeur. Quand tu sorts de ton while, tu déchaîne avec le précédent et tu détruit le courant. Ensuite, tu fais attention à ta valeur retour si ton élément détruit était le premier.
    Si tu n'y arrives pas, demain, je jetterais un coup d'oeil plus en détail.
    Citation Envoyé par miketidy Voir le message
    Pourrais-tu m'aider stp

    Merci,

  11. #11
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France, Somme (Picardie)

    Informations forums :
    Inscription : Mai 2008
    Messages : 217
    Points : 71
    Points
    71
    Par défaut
    Ok Merci, je vais essayer çà et demain je te dis quoi

    Vraiment merci de m'aider

  12. #12
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    Que la proposition 3 te fasse un abort me laisserais penser que tu as peu être un autre problème. Peux-tu debugger pour voir pourquoi cet abort?
    Une autre solution pourrait être:
    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
    CRequeteListe *CRequeteListe::Supprimer( CRequeteSql *pCr)
    {
        CRequeteListe *pCrl= this;
        CRequeteListe *pCrlPrecedent;
        pCrlPrecedent = NULL;
        while((pCrl)&&(pCrl->Element!=pCr){
           pCrlPrecedent = pCrl;
           pCrl = pCrl->Suivant;
        }
        CRequeteListe *pRetour = this;
        if(pCrl){
           if(pCrlPrecedent){
              pCrlPrecedent->Suivant=pCrl->Suivant;
           }
           else{
              pRetour = pCrl->Suivant;
           }
           pCrl->Suivant = NULL;
           delete pCrl;
        }
        return  pRetour;
    }
    Je n'ai pas testé. C'est la trame de l'idée d'hier.

  13. #13
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France, Somme (Picardie)

    Informations forums :
    Inscription : Mai 2008
    Messages : 217
    Points : 71
    Points
    71
    Par défaut
    Ok, je vais essayé de le débugguer mais de toute facon le programme est merdique j'ai eu déjà le cas où le développeur avait une fonction où il essayé de modifier une constante...

    Je testerai çà dans l'après-midi, là je n'ai pas trop le temps...

    Merci beaucoup pour ton aide

  14. #14
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France, Somme (Picardie)

    Informations forums :
    Inscription : Mai 2008
    Messages : 217
    Points : 71
    Points
    71
    Par défaut
    J'ai eu le temps de tester et il me met une erreur :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    *** glibc detected *** free(): invalid pointer: 0xfeff76fc ***
    Je ne sais pas ce que c'est...

  15. #15
    Rédacteur
    Avatar de 3DArchi
    Profil pro
    Inscrit en
    Juin 2008
    Messages
    7 634
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2008
    Messages : 7 634
    Points : 13 017
    Points
    13 017
    Par défaut
    J'aurais tendance à dire que cette fonction n'était pas la seule source de ton problème. Je pense que tu dois investiguer un peu plus. Ca ressemble à une corruption d'une zone mémoire (écrasement), un pointeur invalide, voire un delete fait sur un objet déjà détruit (hypothèse ++ à mon avis).

  16. #16
    Membre régulier
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    217
    Détails du profil
    Informations personnelles :
    Localisation : France, Somme (Picardie)

    Informations forums :
    Inscription : Mai 2008
    Messages : 217
    Points : 71
    Points
    71
    Par défaut
    Ok, je vais regarder de plus près.

    Merci

Discussions similaires

  1. aide sur ce le probleme de segmentation fault
    Par selmani300 dans le forum C++
    Réponses: 3
    Dernier message: 26/03/2009, 07h48
  2. Réponses: 2
    Dernier message: 15/01/2008, 12h09
  3. probleme segmentation fault
    Par eminem313 dans le forum Linux
    Réponses: 2
    Dernier message: 07/06/2007, 21h55
  4. Probleme de segmentation fault avec sprintf
    Par MathG dans le forum C++
    Réponses: 5
    Dernier message: 14/12/2006, 01h12
  5. probleme segmentation fault
    Par newbee33 dans le forum C
    Réponses: 14
    Dernier message: 28/11/2006, 18h55

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