Partage
  • Partager sur Facebook
  • Partager sur Twitter

Programme en C:

erreur de segmentation.

Sujet résolu
    21 novembre 2007 à 3:22:58

    Bonjour à tous,

    Je fais un programme en langage C, me permettant d'implémenter sous forme de Tas, un algorithme de tri de chaîne de caractère.
    La compilation se passe très bien mais lors de l'exécution de mon programme, il me renvoi:
    Erreur de segmentation (core dumped)

    Voici mes 2 fichiers:
    1. #include <stdlib.h>
    2. #include <string.h>
    3. #include "memoire.h"
    4. #include "implementation_tas.h"
    5. static void **t = NULL;
    6. static unsigned dernier_calculer = 0;
    7. /* static unsigned racine = 0; */
    8. /* static void (*compare) (void *, void*) = NULL; */
    9. void
    10. creer_tas (int taille) {
    11.   t = memoire_allouer((taille + 1) * sizeof(*t));
    12. }
    13. unsigned
    14. filsGauche (unsigned sommet) {
    15.   if (t[2*sommet + 1] == NULL)
    16.     return 0;
    17.   else
    18.     return (2*sommet + 1);
    19. }
    20. unsigned
    21. filsDroit (unsigned sommet) {
    22.   if (t[2*sommet + 2] == NULL)
    23.     return 0;
    24.   else
    25.     return (2*sommet + 2);
    26. }
    27. unsigned
    28. pere (unsigned sommet) {
    29.   if (sommet%2 == 0)
    30.     return (sommet/2);
    31.   else
    32.     return ((sommet-1)/2);
    33. }
    34. void
    35. echanger (unsigned s1, unsigned s2) {
    36.   void *tmp =t[s1];
    37.   t[s1] = t[s2];
    38.   t[s2] = tmp;
    39. }
    40. void
    41. insererValeur (char *s) {
    42.   strcpy(t[dernier_calculer],s);
    43. }
    44. void
    45. reorganiseTasMontant (unsigned sommet) {
    46.   unsigned p;
    47.   bool signal;
    48.   p = pere(sommet);
    49.   signal = 1;
    50.   while ((sommet != 0) && (signal == 1)) {
    51.     if (strcmp (t[sommet], t[p]) > 0) {
    52.         echanger (sommet, p);
    53.         sommet = p;
    54.         p = pere(sommet);
    55.       }
    56.     else
    57.       signal = 0;
    58.   }
    59. }
    60. char *
    61. supprimerValeur (void) {
    62.   char *racine = t[0];
    63.   t[0] = t[dernier_calculer];
    64.   return racine;
    65. }
    66. void
    67. reorganiserTasDes (unsigned sommet) {
    68.   unsigned g = filsGauche(sommet);
    69.   unsigned d = filsDroit(sommet);
    70.   if (g != 0) {
    71.     if (strcmp (t[sommet], t[g]) < 0) {
    72.       echanger (sommet, g);
    73.       reorganiserTasDes(g);
    74.     }
    75.   }
    76.   if (d != 0) {
    77.     if (strcmp (t[sommet], t[d]) < 0){
    78.       echanger (sommet, d);
    79.       reorganiserTasDes(d);
    80.     }
    81.   }
    82. }
    83. /* bool */
    84. /* EstFeuille (unsigned sommet) { */
    85. /*   return (filsGauche(t, sommet) == NULL && filsDroit(t, sommet) == NULL); */
    86. /* } */
    87. void
    88. insererDansTas (char *s, int taille) {
    89.   if (t == NULL)
    90.     creer_tas (taille);
    91.   unsigned longueur = strlen(s);
    92.   t[dernier_calculer] = memoire_allouer ((longueur + 1) * sizeof(char));
    93.   insererValeur(s);
    94.   reorganiseTasMontant(dernier_calculer);
    95.   dernier_calculer++;
    96. }
    97. char *
    98. supprimerDansTas (void) {
    99.   char *racine = supprimerValeur();
    100.   reorganiserTasDes(0);
    101.   dernier_calculer--;
    102.   return racine;
    103. }
    104. void
    105. desallocation (unsigned indice) {
    106.   memoire_liberer(t[indice]);
    107. }
    108. void
    109. desallocation_t (void) {
    110.   memoire_liberer(t);
    111. }

    et
    1. #include <stdlib.h>
    2. #include <stdio.h>
    3. #include "memoire.h"
    4. #include "implementation_tas.h"
    5. void
    6. usage (char *s) {
    7.   fprintf (stderr, "usage: %s\n", s);
    8.   exit (EXIT_FAILURE);
    9. }
    10. int
    11. main (int argc, char *argv[]) {
    12.  /*  if (argc < 3) */
    13. /*     usage (argv[0]); */
    14.   argc = 3;
    15.   argv[1] = "test";
    16.   argv[2] = "zzes";
    17.   int targc = argc - 1;
    18.   for (int i = 1; i < argc; i++)
    19.     insererDansTas(argv[i], targc);
    20.   for (int i = 0; i < targc; i++) {
    21.     char *racine = supprimerDansTas();
    22.     printf ("%s", racine);
    23.     desallocation(targc-i);  
    24.   }
    25.   desallocation_t();
    26.   exit(EXIT_SUCCESS);
    27. }

    Voici le retour de la commande valgrind ./trier
    1. ==15115== Memcheck, a memory error detector.
    2. ==15115== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
    3. ==15115== Using LibVEX rev 1732, a library for dynamic binary translation.
    4. ==15115== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
    5. ==15115== Using valgrind-3.2.3-Debian, a dynamic binary instrumentation framework.
    6. ==15115== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
    7. ==15115== For more details, rerun with: -v
    8. ==15115==
    9. ==15115== Conditional jump or move depends on uninitialised value(s)
    10. ==15115==    at 0x804866F: filsDroit (implementation_tas.c:27)
    11. ==15115==    by 0x8048813: reorganiserTasDes (implementation_tas.c:80)
    12. ==15115==    by 0x804896E: supprimerDansTas (implementation_tas.c:114)
    13. ==15115==    by 0x80485BA: main (trier.c:28)
    14. ==15115==
    15. ==15115== Use of uninitialised value of size 4
    16. ==15115==    at 0x40235DE: strcmp (mc_replace_strmem.c:341)
    17. ==15115==    by 0x804884E: reorganiserTasDes (implementation_tas.c:82)
    18. ==15115==    by 0x804896E: supprimerDansTas (implementation_tas.c:114)
    19. ==15115==    by 0x80485BA: main (trier.c:28)
    20. ==15115==
    21. ==15115== Invalid read of size 1
    22. ==15115==    at 0x40235DE: strcmp (mc_replace_strmem.c:341)
    23. ==15115==    by 0x804884E: reorganiserTasDes (implementation_tas.c:82)
    24. ==15115==    by 0x804896E: supprimerDansTas (implementation_tas.c:114)
    25. ==15115==    by 0x80485BA: main (trier.c:28)
    26. ==15115==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
    27. ==15115==
    28. ==15115== Process terminating with default action of signal 11 (SIGSEGV)
    29. ==15115==  Access not within mapped region at address 0x0
    30. ==15115==    at 0x40235DE: strcmp (mc_replace_strmem.c:341)
    31. ==15115==    by 0x804884E: reorganiserTasDes (implementation_tas.c:82)
    32. ==15115==    by 0x804896E: supprimerDansTas (implementation_tas.c:114)
    33. ==15115==    by 0x80485BA: main (trier.c:28)
    34. ==15115==
    35. ==15115== ERROR SUMMARY: 3 errors from 3 contexts (suppressed: 11 from 1)
    36. ==15115== malloc/free: in use at exit: 22 bytes in 3 blocks.
    37. ==15115== malloc/free: 3 allocs, 0 frees, 22 bytes allocated.
    38. ==15115== For counts of detected errors, rerun with: -v
    39. ==15115== searching for pointers to 3 not-freed blocks.
    40. ==15115== checked 59,808 bytes.
    41. ==15115==
    42. ==15115== LEAK SUMMARY:
    43. ==15115==    definitely lost: 0 bytes in 0 blocks.
    44. ==15115==      possibly lost: 0 bytes in 0 blocks.
    45. ==15115==    still reachable: 22 bytes in 3 blocks.
    46. ==15115==         suppressed: 0 bytes in 0 blocks.
    47. ==15115== Rerun with --leak-check=full to see details of leaked memory.
    48. Erreur de segmentation (core dumped)

    Et j'ai également fais tourné mon programme avec GDB.
    Mais même en retournant mon programme dans tous les sens, je n'arrive pas corriger ce message d'erreur.

    Donc si quelqu'un pouvait trouver le problème et surtout me l'expliquer, ce serait sympathique.
    Merci à tous,
    cordialement.
    • Partager sur Facebook
    • Partager sur Twitter
      21 novembre 2007 à 10:18:24

      Coucou ,

      bon j'y connais pas grand chose mais j'ai eu ce probleme et je me suis rendu FOLLE avec ! Alors en gros voila ce que j'avais fait au debut:

      1. void fonction(int nbJoueurs, int *tab)
      2. {
      3. tab = (int*) malloc(nbJoueurs * sizeof(int));
      4. }
      5. int main()
      6. {
      7. int *tab;
      8. fonction(5, tab);
      9. printf("%d", tab[3]);            //en gros c'etait ça
      10. return 0
      11. }


      et bon ben ça n'y manquait pas, ERREUR DE SEGMENTATION !

      et pour que ça marche, j'ai du faire :

      1. int* fonction(int nbJoueurs, int *tab)
      2. {
      3. tab = (int*) malloc(nbJoueurs * sizeof(int));
      4. return tab;
      5. }
      6. int main()
      7. {
      8. int *tab;
      9. tab = fonction(5, tab);
      10. printf("%d", tab[3]);
      11. return 0
      12. }



      Je sais pas trop si ça va t'aider mais je comprend pas trop ton code pour voir exactement...
      Bon courage !
      • Partager sur Facebook
      • Partager sur Twitter
        21 novembre 2007 à 11:17:36

        Il manque ton fichier memoire.c et les deux fichiers d'en-tête.

        EDIT:

        Qu'est-ce qui te fait croire que tu peux faire ça?

        Citation : TatSou-Max

        1. int
        2. main (int argc, char *argv[]) {
        3.  /*  if (argc < 3) */
        4. /*     usage (argv[0]); */
        5.   argc = 3;
        6.   argv[1] = "test";
        7.   argv[2] = "zzes";



        Thierry
        • Partager sur Facebook
        • Partager sur Twitter
          21 novembre 2007 à 13:03:14

          Salut,

          Valgrind te donnes la réponse...
          Il te dit que cette erreur a lieu à la ligne 82 ==> reorganiserTasDes (implementation_tas.c:82).

          La réponse est tout simplement que par moment tu essais d'accéder à t[NULL].

          Ensuite, comme le dit tc, argc = 3, c'est pas terrible...
          Bonne continuation de projet (tu dois être à bordeaux 1 au 3eme semestre d'info toi (cf memoire.h)) ;)
          • Partager sur Facebook
          • Partager sur Twitter
            21 novembre 2007 à 14:13:29

            Merci pour vos réponses.

            Mon memoire.c (bien connu des étudiants de Bordeaux1 ;) )
            1. #include <stdio.h>
            2. #include <stdlib.h>
            3. #include "memoire.h"
            4. static int niveau = 0;
            5. static bool trace = false;
            6. static void
            7. erreur_memoire(char *s)
            8. {
            9.     fprintf(stderr, "Erreur %s mémoire\n", s);
            10.     exit(EXIT_FAILURE);
            11. }
            12. void
            13. memoire_trace(bool mode)
            14. {
            15.     trace = mode;
            16. }
            17. static void
            18. tracer(void *p)
            19. {
            20.   if (trace)
            21.     printf("[memoire : %d (%p)]\n", niveau, p);
            22. }
            23. void *
            24. memoire_allouer(size_t size)
            25. {
            26.     void *p = malloc(size);
            27.     if (p == NULL && size != 0)
            28.         erreur_memoire("allocation");
            29.     niveau++;
            30.     tracer(p);
            31.     return p;
            32. }
            33. void *
            34. memoire_reallouer(void *p, size_t size)
            35. {
            36.   void *q = realloc(p, size);
            37.   if (size != 0 && q == NULL)
            38.     erreur_memoire("reallocation");
            39.   if (p == NULL && q != NULL)      
            40.     niveau++;
            41.   else if (p != NULL && size == 0)      
            42.     niveau--;
            43.   tracer(q);
            44.   return q;
            45. }
            46. void
            47. memoire_liberer(void *p)
            48. {
            49.   free(p);
            50.   if (p != NULL)
            51.     niveau--;    
            52.   tracer(p);
            53. }
            54. int
            55. memoire_balance()
            56. {
            57.   return niveau;
            58. }

            Memoire.h
            1. #ifndef MEMOIRE_H
            2. #define MEMOIRE_H
            3. #include <stddef.h>
            4. #include <stdbool.h>
            5. extern void *memoire_allouer(size_t size);
            6. extern void *memoire_reallouer(void *p, size_t size);
            7. extern void memoire_liberer(void *p);
            8. extern void memoire_trace(bool actif);
            9. extern int memoire_balance();
            10. #endif  /* MEMOIRE */

            implementation_tas.h
            1. #ifndef         COMBINAISON_H_
            2. # define        COMBINAISON_H_
            3. extern void insererDansTas (char *s, int taille);
            4. extern char *supprimerDansTas (void);
            5. void def_compare (int (*f) (void *, void *));
            6. char *chaine_compare (char *s1, char *s2);
            7. char *chaine_compare_inverse (char *s1, char *s2);
            8. int entier_compare (int entier1, int entier2);
            9. int entier_compare_inverse (int entier1, int entier2);
            10. void desallocation (unsigned indice);
            11. void desallocation_t (void);
            12. #endif      /* !COMBINAISON_H_ */


            Pour le argc=3 ben en fait, c'est que sous gdb je ne sais pas comment lancer le programme avec des arguments :/
            Donc gdb me lance toujours mon programme avec argc=1 et argv[1]=NULL donc j'ai pas trouvé mieux, désolé.

            Enfin, avec gdb, j'avais bien remarqué que l'erreur se situé en ligne 82.
            Mais je n'arrive pas à comprendre à quel moment je peux avoir un t[NULL] :/
            Et je pense que si j'arrive à corriger ça, mon programme devrait enfin marcher, j'espère.
            • Partager sur Facebook
            • Partager sur Twitter
              21 novembre 2007 à 14:31:44

              Citation : TatSou-Max


              Mon memoire.c (bien connu des étudiants de Bordeaux1 ;) )



              En effet : memoire.c
              • Partager sur Facebook
              • Partager sur Twitter
                21 novembre 2007 à 17:41:22

                Ben pour gdb avec des raguments tu fais :

                run argument1 ... argumentN
                Tout simplement...
                • Partager sur Facebook
                • Partager sur Twitter
                  21 novembre 2007 à 18:16:49

                  Merci pour gdb, si je précise que je ne le maîtrise pas, cela n'étonnera personne je pense ;)
                  • Partager sur Facebook
                  • Partager sur Twitter
                    21 novembre 2007 à 18:36:21

                    Simple curiosité, tu est dans quel groupe de csb3 : (1,2,3,4,5,ou 6) ?
                    • Partager sur Facebook
                    • Partager sur Twitter
                      21 novembre 2007 à 19:43:39

                      @Vince: Et toi ?

                      Bon alors j'ai résolu le problème.
                      En fait j'avais 2 erreurs:

                      La première, t[0] = t[dernier_calculer] faisait pointer t[0] sur NULL car dernier_calculer pointe en fait vers la première case libre de t.

                      La seconde, desallocation(targc-i) n'était pas au bon endroit.
                      Je libérais la mémoire trop tard.

                      Donc voilà, je vais passer mon topic en résolu
                      et je vous remercie tous pour votre aide.

                      Merci et bonne continuation.
                      • Partager sur Facebook
                      • Partager sur Twitter

                      Programme en C:

                      × 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