Partage
  • Partager sur Facebook
  • Partager sur Twitter

Problème : Segmentation fault (core dumped)

Sujet résolu
    22 septembre 2019 à 19:35:31

    Bonjour,

    lorsque je lance le programme si dessous, il m'écrit en console 'Segmentation fault (core dumped)'.

    Ps: Je suis sur linux et je suis débutant.

    le main.c :

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <ctype.h>
    #include <time.h>
    #ifndef DEF_MAINH
    #define DEF_MAINH
    #include "main.h"
    #endif
    #define MIN 1
    
    int main(int argc, char *argv[])
    {
        int nombreEssais = 10;
        char caractereJoueur = 0;
        char *motMystere = "", motJoueur[strlen(motMystere)];
        choisirMotMystere(motMystere);
    
        for(int i = 0; i < strlen(motMystere); i++)
        {
            motJoueur[i] = '*';
        }
    
        printf("Bienvenue dans le jeu du pendu !\n");
        printf("Le but est de trouver un mot en moins de 10 essais.\n");
        printf("Bonne chance :)\n\n");
    
        do
        {
        printf("Il vous reste %d essais.\n", nombreEssais);
        printf("Tapez une lettre (en majuscule) %s : ", motJoueur);
        caractereJoueur = lireCaractere();
        nombreEssais = comparerMot(caractereJoueur, motMystere, motJoueur, nombreEssais);
        } while(strcmp(motMystere, motJoueur) != 0 && nombreEssais > 0);
    
        if(strcmp(motMystere, motJoueur) == 0)
        {
            printf("Vous avez gagné, le mot était %s\n\n", motMystere);
        }
        else
        {
            printf("Vous avez perdu :(, le mot était %s\n\n", motMystere);
        }
    
        return 0;
    }
    
    char lireCaractere()
    {
        char caractere = getchar();
        caractere = toupper(caractere);
    
        while(getchar() != '\n');
    
        return caractere;
    }
    
    int comparerMot(char caractere, char *motMystere, char *motJoueur, int nombreEssais)
    {
        int distanceCaractere = 0;
        char *PointeurCaractere = strchr(motMystere, caractere);
    
        if(PointeurCaractere == NULL)
        {
            nombreEssais--;
        }
    
        while(PointeurCaractere != NULL)
        {
            distanceCaractere = strlen(motMystere) - strlen(PointeurCaractere);
            motJoueur[distanceCaractere] = caractere;
    
            PointeurCaractere++;
            PointeurCaractere = strchr(PointeurCaractere, caractere);
        }
        return nombreEssais;
    }
    
    void choisirMotMystere(char *motMystere)
    {
        FILE *chercherMotMystere = NULL;
    
        chercherMotMystere = fopen("mot_mystere.txt", "r");
    
        if(chercherMotMystere == NULL)
        {
            exit(0);
        }
        srand(time(NULL));
    
        int nombreMotsMysteres = 0, nombreMots = 0;
    
        while(fgets(motMystere, 1000, chercherMotMystere) != NULL)
        {
            nombreMotsMysteres++;
        }
    
        nombreMots = (rand() % (nombreMotsMysteres - MIN + 1)) + MIN;
    
        rewind(chercherMotMystere);
    
        for(int e = 0; e < nombreMots; e++)
        {
            fgets(motMystere, 1000, chercherMotMystere);
        }
        fclose(chercherMotMystere);
    }

    Le main.h

    char lireCaractere();
    int comparerMot(char caractere, char *motMystere, char *motJoueur, int nombreEssais);
    void choisirMotMystere(char *motMystere);
    




    • Partager sur Facebook
    • Partager sur Twitter
      22 septembre 2019 à 20:26:01

      Bonjour ! Ce que tu peux faire, c'est mettre plein de "printf" partout afin de voir à quel endroit précis du programme le plantage a lieu. Ensuite, si tu ne vois toujours pas le problème, dis-nous où le plantage a eu lieu et ce sera plus facile. (Là, juste en lisant le code, je ne vois pas trop ce qu'on peut faire pour avancer.)
      • Partager sur Facebook
      • Partager sur Twitter
        22 septembre 2019 à 20:43:41

        Je crois qu'il n'y a pas besoin de chercher bien loin !

        Dès la ligne 16 ça ne va pas : motMystere pointe sur une chaîne en lecture seule, et tu tentes plus loin dans ton code d'écrire dedans.

        sur la même ligne quel taille penses-tu que fera la chaîne motJoueur 

        • Partager sur Facebook
        • Partager sur Twitter
          23 septembre 2019 à 6:34:02

          Merci pour vos réponses,J'ai réussi à avancer grâce a vous.

          Maintenant il ne fait plus 'Segmentation fault' mais lorsque je fait :

          int a = strlen(motMystere);
          printf("%d", a);

          Il est 1 fois plus grand, exemple; le mot DEUX, il va me répondre qu'il fait 5 en taille.

          De plus il rajoute des caractères :

           

          Voici mon main.c modifié :

          #include <stdio.h>
          #include <stdlib.h>
          #include <string.h>
          #include <ctype.h>
          #include <time.h>
          #ifndef DEF_MAINH
          #define DEF_MAINH
          #include "main.h"
          #endif
          #define MIN 1
          
          int main(int argc, char *argv[])
          {
              int nombreEssais = 10;
              char caractereJoueur = 0;
              char *motMystere = choisirMotMystere();
              char  motJoueur[strlen(motMystere)];
          
              for(int i = 0; i < strlen(motMystere); i++)
              {
                  motJoueur[i] = '*';
              }
                  printf("Bienvenue dans le jeu du pendu !\n");
              printf("Le but est de trouver un mot en moins de 10 essais.\n");
              printf("Bonne chance :)\n\n");
          
              do
              {
              printf("Il vous reste %d essais.\n", nombreEssais);
              printf("Tapez une lettre (en majuscule) %s : ", motJoueur);
              caractereJoueur = lireCaractere();
              nombreEssais = comparerMot(caractereJoueur, motMystere, motJoueur, nombreEssais);
              } while(strcmp(motMystere, motJoueur) != 0 && nombreEssais > 0);
          
              if(strcmp(motMystere, motJoueur) == 0)
              {
                  printf("Vous avez gagné, le mot était %s\n\n", motMystere);
              }
              else
              {
                  printf("Vous avez perdu :(, le mot était %s\n\n", motMystere);
              }
          
              return 0;
          }
          
          char lireCaractere()
          {
              char caractere = getchar();
              caractere = toupper(caractere);
          
              while(getchar() != '\n');
          
              return caractere;
          }
          
          int comparerMot(char caractere, char *motMystere, char *motJoueur, int nombreEssais)
          {
              int distanceCaractere = 0;
              char *PointeurCaractere = strchr(motMystere, caractere);
          
              if(PointeurCaractere == NULL)
              {
                  nombreEssais--;
              }
          
              while(PointeurCaractere != NULL)
              {
                  distanceCaractere = strlen(motMystere) - strlen(PointeurCaractere);
                  motJoueur[distanceCaractere] = caractere;
          
                  PointeurCaractere++;
                  PointeurCaractere = strchr(PointeurCaractere, caractere);
              }
              return nombreEssais;
          }
          
          char* choisirMotMystere()
          {
              FILE *chercherMotMystere = NULL;
          
              chercherMotMystere = fopen("mot_mystere.txt", "r");
          
              if(chercherMotMystere == NULL)
              {
                  exit(0);
              }
              srand(time(NULL));
          
              int nombreMotsMysteres = 0, nombreMots = 0;
              char *motMystere;
          
              while(fgets(motMystere, 1000, chercherMotMystere) != NULL)
              {
                  nombreMotsMysteres++;
              }
          
              nombreMots = (rand() % (nombreMotsMysteres - MIN + 1)) + MIN;
          
              rewind(chercherMotMystere);
          
              for(int e = 0; e < nombreMots; e++)
              {
                  fgets(motMystere, 1000, chercherMotMystere);
              }
          
              fclose(chercherMotMystere);
          
              return motMystere;
          }




          • Partager sur Facebook
          • Partager sur Twitter
            23 septembre 2019 à 14:38:03

            Bienvenue dans le monde merveilleux de l'encodage de caractères !

            En effet, C possède des chaînes de caractères sur un octet qui est largement suffisant pour la table ASCII. En revanche, avec le temps, on a du intégrer le support des autres langues, autres lettres, autres alphabet, etc. Et tout ça finalement dépasse la taille d'un caractère et pour ça, plusieurs dieux ont inventés un concept simple : UTF-8.

            En réalité, une chaîne de caractère contiendra des octets à la suite qui peuvent être plus nombreux que le vrai nombre de lettres du texte. Exemples :

            • abc -> 3 octets, 3 caractères
            • abé -> 4 octets, 3 caractères (é vaut 233 en UTF-8 et nécessitent donc 2 octets).

            En bref, strlen n'est pas compatible UTF-8 et doit uniquement être utilisé avec des chaînes ASCII si ton but est d'obtenir le nombre réel de caractères.

            Notes : cette explication est succinte, en réalité il y a d'autres encodages disponibles que UTF-8, mais en 2019 il y a aucune raison d'utiliser autre chose.

            Mais à part ça il y a plusieurs choses qui ne vont pas dans ton code. N'oublie pas non plus que fgets stocke le '\n' final trouvé (\r\n sur windows) dans la ligne. Donc si tu es sur Linux, il est problable que ton mot contiennent DEUX\n (donc 5 caractères et non 4).

            -
            Edité par markand 23 septembre 2019 à 14:41:54

            • Partager sur Facebook
            • Partager sur Twitter

            git is great because Linus did it, mercurial is better because he didn't.

              23 septembre 2019 à 19:01:28

              Merci beaucoup Markand, tu m'a appris pas mal de chose ! :)

              Du coup est-ce qu'il existe un autre moyen de collecter le réel nombre de caractères qu'il y a dans une chaine.

              Pour le \n je peux me débrouiller tout seul pour pouvoir l'enlever.

              Merci d'avance :).

              • Partager sur Facebook
              • Partager sur Twitter
                23 septembre 2019 à 20:46:20

                Tu n'a plus de "segmentation fault", c'est un coup de bol : dans ta fonction choisirMotMystere, ligne 91, tu déclares un pointeur motMystere que tu utilises plus loin dans ton code, sans l'initialiser !

                -
                Edité par rouloude 23 septembre 2019 à 20:58:54

                • Partager sur Facebook
                • Partager sur Twitter
                  23 septembre 2019 à 20:53:42

                  Salut Rouloude,

                  Je ne comprends très bien, dans la fonction choisirMotMystere j'ai initialisé motMystere et dans la fonction main je l'ai aussi initialisé L16.

                  • Partager sur Facebook
                  • Partager sur Twitter
                    23 septembre 2019 à 21:00:23

                    Non tu ne l'a pas initialisé ! Dans la fonction main, ce n'est pas la même variable.

                    Les caractères superflu vienne du fait que tu n'as pas mis le caractère de fin de chaîne à ta chaîne motJoueur que tu affiches ligne 37 de la fonction main.

                    -
                    Edité par rouloude 23 septembre 2019 à 21:01:29

                    • Partager sur Facebook
                    • Partager sur Twitter
                      24 septembre 2019 à 12:47:30

                      Ligne 91 tu déclarer un pointeur que tu n'initialises pas et que tu utilises ensuite, comme il a été dit, coup de chance que tu ne crash pas.
                      • Partager sur Facebook
                      • Partager sur Twitter
                        25 septembre 2019 à 16:15:16

                        Je viens de voir mon problème merci beaucoup de m'avoir aidé.
                        • Partager sur Facebook
                        • Partager sur Twitter
                          26 septembre 2019 à 8:51:43

                          La prochaine fois, utilise le debugger aussi. Quand on développe et que ça plante on ne s'amuse pas à deviner d'où ça vient :)
                          • Partager sur Facebook
                          • Partager sur Twitter

                          git is great because Linus did it, mercurial is better because he didn't.

                          Problème : Segmentation fault (core dumped)

                          × Après avoir cliqué sur "Répondre" vous serez invité à vous connecter pour que votre message soit publié.
                          × Attention, ce sujet est très ancien. Le déterrer n'est pas forcément approprié. Nous te conseillons de créer un nouveau sujet pour poser ta question.
                          • Editeur
                          • Markdown