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 :

Erreur de segmentation strlen


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Rien
    Inscrit en
    Octobre 2010
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Rien

    Informations forums :
    Inscription : Octobre 2010
    Messages : 25
    Points : 17
    Points
    17
    Par défaut Erreur de segmentation strlen
    Salut

    Je cherche depuis le début de l'aprem pourquoi j'ai cette erreur de segmentation à la ligne 34 comme me l'indique valgrind:

    ==22538== Memcheck, a memory error detector
    ==22538== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
    ==22538== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
    ==22538== Command: ./oo
    ==22538==
    ==22538== Invalid read of size 1
    ==22538== at 0x402701D: strlen (mc_replace_strmem.c:282)
    ==22538== by 0x8048724: __NumGroupe__inputData (fct_arbitre.c:34)
    ==22538== by 0x80485A8: main (main.c:7)
    ==22538== Address 0x63 is not stack'd, malloc'd or (recently) free'd
    ==22538==
    ==22538==
    ==22538== Process terminating with default action of signal 11 (SIGSEGV)
    ==22538== Access not within mapped region at address 0x63
    ==22538== at 0x402701D: strlen (mc_replace_strmem.c:282)
    ==22538== by 0x8048724: __NumGroupe__inputData (fct_arbitre.c:34)
    ==22538== by 0x80485A8: main (main.c:7)
    ==22538== If you believe this happened as a result of a stack
    ==22538== overflow in your program's main thread (unlikely but
    ==22538== possible), you can try to increase the size of the
    ==22538== main thread stack using the --main-stacksize= flag.
    ==22538== The main thread stack size used in this run was 8388608.
    ==22538==
    ==22538== HEAP SUMMARY:
    ==22538== in use at exit: 363 bytes in 5 blocks
    ==22538== total heap usage: 5 allocs, 0 frees, 363 bytes allocated
    ==22538==
    ==22538== LEAK SUMMARY:
    ==22538== definitely lost: 3 bytes in 3 blocks
    ==22538== indirectly lost: 0 bytes in 0 blocks
    ==22538== possibly lost: 0 bytes in 0 blocks
    ==22538== still reachable: 360 bytes in 2 blocks
    ==22538== suppressed: 0 bytes in 0 blocks
    ==22538== Rerun with --leak-check=full to see details of leaked memory
    ==22538==
    ==22538== For counts of detected and suppressed errors, rerun with: -v
    ==22538== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 11 from 6)
    Erreur de segmentation

    Voici mon projet, il s'agit de tirer la première et la dernière syllabe d'un mot donné à partir d'un dicionnaire orthosyllabique de ce type:

    a capella|a-ca-pel-la
    a cappella|a-cap-pel-la
    a contrario|a-con-tra-rio
    a fortiori|a-for-tio-ri
    a giorno|a-gior-no
    a l'instar|a-l'ins-tar
    a posteriori|a-pos-te-rio-ri
    a priori|a-prio-ri
    ab absurdo|ab-ab-sur-do
    ab initio|ab-i-ni-tio
    ab ovo|ab-o-vo
    abaca|a-ba-ca
    abaissaient|a-bais-saient
    abaissait|a-bais-sait
    ...
    ...

    dans des structures t_Mot placées dans une structure Dico.

    Voici mes fichiers:

    fct_arbitre.c:
    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    #include "fct_arbitre.h"
    #include <stdlib.h>
    #include <stdio.h>
     
    Dico* __NumGroupe__inputData(char* filename)
    {
          Dico* dico = malloc(sizeof(Dico));
          FILE* file = NULL;
          file = fopen(filename,"r");
     
          int pipe = 0;
          int first_syll_trouve=0;
     
          t_Mot* current_t_mot= dico->premier; // on declare le maillon actuel comme etant le 1er de la structure
     
          char currentchar = fgetc(file);
    	currentchar = fgetc(file);
     
          while(currentchar != EOF)
          {
           char* word_tmp = (char*)malloc(sizeof(char)); // a chaque fois qu'on aura fini une ligne on redeclarera un nouveau mot de maniere dynamique - liberé ensuite a la fin de la boucle
           word_tmp = fgetc(file);
           char* first_tmp = (char*)malloc(sizeof(char));// variable servant a recuperer la 1ere syllabe du mot
           first_tmp= NULL;
           char* last_tmp = (char*)malloc(sizeof(char));// variable servant a recuperer la derniere syllabe du mot
           last_tmp= NULL;
     
              while(currentchar != '\n')
              {
                if(currentchar != '|')
                {
                     if(pipe == 0)
                     {   
                             word_tmp = (char*) realloc(word_tmp, strlen(word_tmp)+1);
                             word_tmp = strcat(word_tmp, &currentchar);
                             currentchar=fgetc(file);
                     }
                     else
                     {
                        while (currentchar!= '\n')
                        {
                                  while ((currentchar != '-')&&(first_syll_trouve==0))
                                  {
                                        first_tmp = (char*) realloc(first_tmp, strlen(first_tmp)+1);
                                        first_tmp= strcat(first_tmp, &currentchar);
                                        currentchar=fgetc(file);
                                  }
                                  first_syll_trouve=1;
     
                                  if ((currentchar !='-')&& (first_syll_trouve==1))
                                  {
                                        last_tmp = (char*)realloc(last_tmp, strlen(last_tmp)+1);
                                        last_tmp= strcat(last_tmp, &currentchar);
                                        currentchar= fgetc(file);
                                  }
                                  else if (currentchar == '-')
                                  {
                                       free(last_tmp);
                                       last_tmp = (char*)malloc(sizeof(char));// on aloue de nouveau de la memoire pour last_tmp, puis redeclaration a NULL
                                       last_tmp= NULL;
                                       currentchar= fgetc(file);                                                                      
                                  }
                        }// lorsque l'on sort de cette boucle, on est a \n , et donc on sort egalement de la 1ere boucle. On a parcouru toute notre ligne.
                     }
                }
                else
                {
                     pipe = 1;
                     currentchar = fgetc(file);
                }
     
              }
              //creation t_mot
              current_t_mot->first_syllabe=first_tmp;
              current_t_mot->last_syllabe=last_tmp;
              current_t_mot->word=word_tmp; // on passe le mot, syllabes, alloués dynamiquement dans la structure
              current_t_mot->used=0;
     
              current_t_mot= current_t_mot->next_word; // incrementation au t_mot suivant dans la structure
              pipe=0;
              first_syll_trouve=0;
     
              free(word_tmp); // liberation du mot,syllabes, alloués dynamiquement
              free(first_tmp);
              free(last_tmp);
     
          }
     
        fclose(file);
        return dico;
    }
     
    etc...
    fct_arbitre.h:
    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
    typedef struct t_Mot{
            char* word;
            char* first_syllabe;
            char* last_syllabe;
            struct t_Mot* next_word;
            int used;
            }t_Mot;
     
    typedef struct{
            t_Mot* premier;
            t_Mot* dernier;
            }Dico;
     
    Dico* __NumGroupe__inputData(char* filename);
     
    void __NumGroupe__freeData(Dico* dico);
     
    char* __NumGroupe__getNextWord(Dico* dico, char* current_word);
     
    void __NumGroupe__removeWord(Dico* dico, char * current_word);
     
    void __NumGroupe__reloadDictionary(Dico* data);
    main.c:
    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
    #include "fct_arbitre.h"
     
    int main()
    {
     
    Dico* result;
    result=  __NumGroupe__inputData("dictionnaire-orthoSyllabique-utf8.txt");
     
    //premier mot
    char* mot1=result->premier->word;
    char* dernsyllabe1=result->premier->last_syllabe;
    char* premsyllabe1=result->premier->first_syllabe;
     
    //dernier mot
    char* mot2=result->dernier->word;
    char* dernsyllabe2=result->dernier->last_syllabe;
    char* premsyllabe2=result->dernier->first_syllabe;
     
    printf("voici le premier mot %s avec sa premiere syllabe %s et sa derniere syllabe %s \n",mot1, premsyllabe1,dernsyllabe1 );
    printf("voici le dernier mot %s avec sa premiere syllabe %s et sa derniere syllabe %s \n",mot2, premsyllabe2,dernsyllabe2 );
     
     
     
      return 0;
    }
    Si vous voyez aussi quelque chose d'illogique n'hésitez pas à m'en faire part

    Votre aide me sera infiniment précieuse, merci d'avance

    Xavi91

  2. #2
    Membre habitué
    Homme Profil pro
    Inscrit en
    Janvier 2011
    Messages
    247
    Détails du profil
    Informations personnelles :
    Sexe : Homme

    Informations forums :
    Inscription : Janvier 2011
    Messages : 247
    Points : 163
    Points
    163
    Par défaut
    Essaye en donnant une valeur initiale à word_tmp. Parce que là tu fais un strlen() d'une chaîne non initialisée.

  3. #3
    Membre expérimenté Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Points : 1 396
    Points
    1 396
    Par défaut
    Il y a bien une valeur dans word_tmp après le fgetc.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char* word_tmp = (char*)malloc(sizeof(char)); // a chaque fois qu'on aura fini une ligne on redeclarera un nouveau mot de maniere dynamique - liberé ensuite a la fin de la boucle
           word_tmp = fgetc(file);
    Par contre, tu déclares une chaine de caractère de 1 caractère. Or on sait, que en C, chaque chaine de caractère doit se terminer par le symbole '\0'. Donc strlen va chercher ce symbole, qu'il ne trouvera pas à word_tmp[0] et qu'il ira chercher à word_tmp[1] donc segfault, car word_tmp[1] n'est pas alloué.

    D'autre part, et sans avoir compris ton code, je ne suis pas sur qu'il soit judicieux de faire autant de realloc. (Allouer une chaine assez grande dès le début ?).

    Bon codage !

  4. #4
    Membre à l'essai
    Homme Profil pro
    Rien
    Inscrit en
    Octobre 2010
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Rien

    Informations forums :
    Inscription : Octobre 2010
    Messages : 25
    Points : 17
    Points
    17
    Par défaut
    J'ai modifié ma fonction ainsi:
    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
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    #include "fct_arbitre.h"
    #include <stdlib.h>
    #include <stdio.h>
     
    Dico* __NumGroupe__inputData(char* filename)
    {
          Dico* dico = malloc(sizeof(Dico));
          FILE* file = NULL;
          file = fopen(filename,"r");
     
          int pipe = 0;
          int first_syll_trouve=0;
     
          dico->premier = malloc(sizeof(t_Mot));
          t_Mot* current_t_mot = dico->premier; // on declare le maillon actuel comme etant le 1er de la structure
     
          char currentchar[2];
    	currentchar[0] = fgetc(file);
        currentchar[1] = '\0';
     
          while(currentchar[0] != EOF)
          {
           char word_tmp[100];
           word_tmp[0]  = '\0';
           char first_tmp[100];
            first_tmp[0]  = '\0';
           char last_tmp[100];
            last_tmp[0]  = '\0';
     
              while(currentchar[0] != '\n')
              {
                if(currentchar[0] != '|')
                {
                     if(pipe == 0)
                     {
                             strcat(word_tmp, currentchar);
                             currentchar[0]=fgetc(file);
                     }
                     else
                     {
                        while (currentchar[0] != '\n')
                        {
                                  while ((currentchar[0] != '-')&&(first_syll_trouve==0))
                                  {
                                        strcat(first_tmp, currentchar);
                                        currentchar[0]=fgetc(file);
                                  }
                                  first_syll_trouve=1;
     
                                  if ((currentchar[0] != '-')&& (first_syll_trouve==1))
                                  {
                                        strcat(last_tmp, currentchar);
                                        currentchar[0]= fgetc(file);
                                  }
                                  else if (currentchar[0] == '-')
                                  {
                                       last_tmp[0] = '\0';
                                       currentchar[0]= fgetc(file);                                                                      
                                  }
                        }// lorsque l'on sort de cette boucle, on est a \n , et donc on sort egalement de la 1ere boucle. On a parcouru toute notre ligne.
                     }
                }
                else
                {
                     pipe = 1;
                     currentchar[0] = fgetc(file);
                }
     
              }
              //creation t_mot
                current_t_mot->first_syllabe= malloc(sizeof(char)*100);
                current_t_mot->first_syllabe = first_tmp;
     
              current_t_mot->last_syllabe=last_tmp;
              current_t_mot->word=word_tmp; // on passe le mot, syllabes, alloués dynamiquement dans la structure
              current_t_mot->used=0;
     
              current_t_mot= current_t_mot->next_word; // incrementation au t_mot suivant dans la structure
              pipe=0;
              first_syll_trouve=0;
     
     
          }
     
        dico->dernier = current_t_mot;
     
        fclose(file);
        return dico;
    }
    mais maintenant j'ai cette erreur avec valgrind:

    ==4553== Memcheck, a memory error detector
    ==4553== Copyright (C) 2002-2010, and GNU GPL'd, by Julian Seward et al.
    ==4553== Using Valgrind-3.6.1 and LibVEX; rerun with -h for copyright info
    ==4553== Command: ./oo
    ==4553==
    ==4553== Use of uninitialised value of size 4
    ==4553== at 0x8048855: __NumGroupe__inputData (fct_arbitre.c:71)
    ==4553== by 0x8048598: main (main.c:7)
    ==4553==
    ==4553== Invalid write of size 4
    ==4553== at 0x8048855: __NumGroupe__inputData (fct_arbitre.c:71)
    ==4553== by 0x8048598: main (main.c:7)
    ==4553== Address 0x4 is not stack'd, malloc'd or (recently) free'd
    ==4553==
    ==4553==
    ==4553== Process terminating with default action of signal 11 (SIGSEGV)
    ==4553== Access not within mapped region at address 0x4
    ==4553== at 0x8048855: __NumGroupe__inputData (fct_arbitre.c:71)
    ==4553== by 0x8048598: main (main.c:7)
    ==4553== If you believe this happened as a result of a stack
    ==4553== overflow in your program's main thread (unlikely but
    ==4553== possible), you can try to increase the size of the
    ==4553== main thread stack using the --main-stacksize= flag.
    ==4553== The main thread stack size used in this run was 8388608.
    ==4553==
    ==4553== HEAP SUMMARY:
    ==4553== in use at exit: 580 bytes in 5 blocks
    ==4553== total heap usage: 5 allocs, 0 frees, 580 bytes allocated
    ==4553==
    ==4553== LEAK SUMMARY:
    ==4553== definitely lost: 200 bytes in 2 blocks
    ==4553== indirectly lost: 0 bytes in 0 blocks
    ==4553== possibly lost: 0 bytes in 0 blocks
    ==4553== still reachable: 380 bytes in 3 blocks
    ==4553== suppressed: 0 bytes in 0 blocks
    ==4553== Rerun with --leak-check=full to see details of leaked memory
    ==4553==
    ==4553== For counts of detected and suppressed errors, rerun with: -v
    ==4553== Use --track-origins=yes to see where uninitialised values come from
    ==4553== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 11 from 6)
    Erreur de segmentation

  5. #5
    Membre expérimenté Avatar de Trademark
    Profil pro
    Inscrit en
    Février 2009
    Messages
    762
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Février 2009
    Messages : 762
    Points : 1 396
    Points
    1 396
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    current_t_mot->last_syllabe=last_tmp;
    Et puis tu affectes current_t_mot à ton dico que tu retournes. last_tmp étant une variable locale, la zone mémoire sera désallouée à la sortie de la fonction et donc dico->dernier->first_syllabe ne sera pas bon. Il faut que tu fasses un strcpy ou un memcpy.

  6. #6
    Expert confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2006
    Messages
    2 937
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations forums :
    Inscription : Septembre 2006
    Messages : 2 937
    Points : 4 358
    Points
    4 358
    Par défaut
    Citation Envoyé par Trademark Voir le message
    Il y a bien une valeur dans word_tmp après le fgetc.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    char* word_tmp = (char*)malloc(sizeof(char)); // a chaque fois qu'on aura fini une ligne on redeclarera un nouveau mot de maniere dynamique - liberé ensuite a la fin de la boucle
           word_tmp = fgetc(file);
    non seulement fgetc renvoit un int pas un char, mais en plus vous assignez le int renvoyé par fgetc à la variable qui contient l'adresse du tableau de 1 char que vous venez d'allouer par malloc (ce qui crée un memory leak au passage) : après cette opération word_tmp pointe vers une adresse mémoire quelconque entre 0 et 255 ou sur 0xFFFFFFFF (ou 0xFFFFFFFFFFFFFFFF si vous compilez en 64 bits),-.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    int word_tmp = fgetc(file) ;

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
          while(currentchar[0] != EOF)
    currentchar étant un tableau de char [-128;127] et EOF étant (int)-1, vous comparez un char avec un int
    lisez fgetc dans un int et assignez currentchar seulement si ce int != EOF

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
               current_t_mot->first_syllabe= malloc(sizeof(char)*100);
                current_t_mot->first_syllabe = first_tmp;
    -> memory leak : la valeur retournée par malloc est écrasée et perdue définitivement

    first_tmp est un tableau sur le stack qui n'a aucune validité une fois la fonction qui le déclare terminée :
    mettre une telle valeur dans une structure de donnée qui survit à l'exécution de la fonction ne peut que conduire à des plantages.

    (en plus first_tmp n'est jamais modifié dans la boucle : toutes les entrées de la structure pointeront vers les mêmes données…)

    etc.

  7. #7
    Membre à l'essai
    Homme Profil pro
    Rien
    Inscrit en
    Octobre 2010
    Messages
    25
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Rien

    Informations forums :
    Inscription : Octobre 2010
    Messages : 25
    Points : 17
    Points
    17
    Par défaut
    @Trademark:
    Même erreur en utilisant memcpy ou strcpy :/

    @JeitEmgie:
    Le code du premier post a été modifié, pouvez vous vous baser sur le dernier code de fct_arbitre.c ?

    Cordialement, Xavi.

Discussions similaires

  1. Erreurs de segmentation !
    Par anti-conformiste dans le forum Applications et environnements graphiques
    Réponses: 16
    Dernier message: 18/10/2005, 11h11
  2. Erreur de segmentation
    Par Trunks dans le forum C
    Réponses: 3
    Dernier message: 06/10/2005, 18h28
  3. Erreur de segmentation (Inconnue)
    Par Dark-Meteor dans le forum C
    Réponses: 5
    Dernier message: 08/09/2005, 13h42
  4. [Dev-C++] Erreur de segmentation...
    Par sas dans le forum Dev-C++
    Réponses: 11
    Dernier message: 26/03/2005, 14h25
  5. erreur de segmentation
    Par transistor49 dans le forum C++
    Réponses: 10
    Dernier message: 15/03/2005, 11h18

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