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 :

Une erreur venant de nullle part


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 6
    Par défaut Une erreur venant de nullle part
    Bonjour, ca fait déjà un an que je programme en C et j'essaye de créer une fonction qui m'affiche les valeurs d'une file

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void AfficherFile(File_carac *tete)
    {
    	while (tete != NULL)
    	{
    		printf("%i %c\n",tete->n,tete->c);
    		tete = tete->suiv;
    	}
    }
    Le problème est que j'obtient parfois une erreur de bus, parfois une erreur de segmentation et parfois aucune erreurs.
    La file est bien initialisé et je ne vois pas d'où ca peu venir (ni ce que c'est une erreur de bus ou de segmentation)

  2. #2
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut Re: Une erreur venant de nullle part
    Citation Envoyé par elaum
    Bonjour, ca fait déjà un an que je programme en C et j'essaye de créer une fonction qui m'affiche les valeurs d'une file
    file ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    void AfficherFile(File_carac *tete)
    {
    	while (tete != NULL)
    	{
    		printf("%i %c\n",tete->n,tete->c);
    		tete = tete->suiv;
    	}
    }
    Ah, liste chainée...
    Le problème est que j'obtient parfois une erreur de bus, parfois une erreur de segmentation et parfois aucune erreurs.
    Il y a un comportement indéfini quelque part...
    La file est bien initialisé
    On veut bien te croire, mais on veut voir le code.

    Poste une version compilable réduite au minimum qui montre le défaut.

    Sinon, donne un lien vers le code complet.

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2005
    Messages
    6
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2005
    Messages : 6
    Par défaut
    Le code complet est disponible (temporairement) sur mon site ici : http://elaum.free.fr/Depot/main.c

  4. #4
    Rédacteur/Modérateur
    Avatar de Trap D
    Profil pro
    Inscrit en
    Septembre 2003
    Messages
    4 942
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2003
    Messages : 4 942
    Par défaut
    Salut
    J'ai regardé ton code et j'ai vu quelques petits problèmes :
    tu ne vérifies pas le retour de fopen, si tu donnes un nom de fichier incorrect, ça plante.

    non verification des retours de malloc et calloc.

    non initialisation de tous les champs de la structure pointée par nouveau (nouveau->suiv = NULL).

    la boucle de lecture des caractères du fichier
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    while ((c =fgetc(flux)) != EOF)
       (*(t + c))++;
    Au fait, pourquoi ne pas écrire t[c]++; c'est trop lisible ? feof(flux) ne fait pas ce que tu crois.

    le point essentiel de la plante, tu as oublié que bidon est une variable locale de ta fonction ConstruireLaFile(int *t, int taille). Avec ta méthode, bidon est le dernier maillon de ta liste et donc à l'affichage il y a plante puisque l'adresse correspondant n'a plus aucune valeur (on est sorti de la fonction ConstruireLaFile !
    "La haine seule fait des choix" - Koan Zen
    "Il ne faut pas être meilleur que les autres, il faut être meilleur que soi." Albert Jacquard
    "Ceux qui savent où ils ont posé leur parapluie ne sont pas alcooliques." - pgibonne.
    Faites du Prolog, ça vous changera les idées !
    Ma page Prolog
    Mes codes sources commentés

    Mon avatar : La Madeleine à la veilleuse de Georges de La Tour

  5. #5
    Expert éminent
    Avatar de Emmanuel Delahaye
    Profil pro
    Retraité
    Inscrit en
    Décembre 2003
    Messages
    14 512
    Détails du profil
    Informations personnelles :
    Âge : 68
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Décembre 2003
    Messages : 14 512
    Par défaut
    Citation Envoyé par elaum
    Le code complet est disponible (temporairement) sur mon site ici : http://elaum.free.fr/Depot/main.c
    Je n'ai pas de solution, mais un certain nombre de points sont etranges (-ed-) :
    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
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <limits.h>
     
    typedef struct filecarac
    {
       int n;
       char c;
       struct filecarac *suiv;
    }
    File_carac;
     
    static int occurenceLettre (const char *fluxstr, int *t)
    /* Cette fonction etudie statistiquement le fichier texte
       Elle prend le nom du fichier a etudier et le tableau a remplir (256cases) */
    {
    /* -ed- ajoute code erreur. */
       int err = 0;
       FILE *flux;                  /* le fichier A. lire */
       flux = fopen (fluxstr, "r"); /* Ouvre ce fichier */
       /* -ed l'ouverture peut echouer... */
       if (flux != NULL)
       {
          /* Tant que la fin du fichier n'est pas atteinte */
          while (!feof (flux))
          {
             /* -ed-
                ce n'est pas la bonne facon de tester la fin de lecture.
                Il faut detecter le EOF retourne par fgetc().
              */
             /* On incremente la case du tableau t correspondant au caractere d'1 */
             /* -ed- suppression syntaxe inadaptee... */
             t[fgetc (flux)]++;
          }
    /* -ed-
       La plage est 0-255.
       Lorsque fgetc() retourne EOF (int < 0), il se passe quoi ? BOUM!
     */
     
          fclose (flux);            /* ferme le fichier */
       }
       else
       {
          perror (fluxstr);
          err = 1;
       }
       /* retourne le tableau */
       /* -ed- aucun interet. Par contre, le code d'erreur est utile. */
       return err;
    }
     
    static void afficherTableauLettre (int *t, int taille)
    {
       int i;
       for (i = 0; i < taille; i++)
       {
          if (t[i] > 0)
          {
             printf ("%c : %i\n", i, *(t + i));
          }
       }
    }
     
    static File_carac *ConstruireLaFile (int *t, int taille)
    /*Cette fonction construit la file en O(n) dans le meilleur des cas et en O(n2) dans le pire */
    /* pourtous les caracs
       si le carac est present dans le texte
       Allouer un item et recuperer ses valeurs
       parcourir la file tant que item.n <= itemcourrant.n
       inserer l'item
     */
    {
       int i;
       File_carac *tete, *nouveau, bidon;
       bidon.n = INT_MAX;
       bidon.c = '?';
       bidon.suiv = NULL;
     
       /* Initialisation de la tete */
       /* -ed- avec une structure non allouee ? */
       tete = &bidon;
     
       /* Pour tous les caracteres */
       for (i = 0; i < taille; i++)
       {
          /* -ed- suppression syntaxe inadaptee... */
          if (t[i] != 0)            /* Si le caractere a inserer est dans le fichier */
          {
             /* Initialise l'item a inserer dans la file */
     
             /* -ed- suppression du cast inutile */
             nouveau = malloc (sizeof (File_carac));
             /* -ed- malloc() peut echouer... */
             if (nouveau != NULL)
             {
                nouveau->n = t[i];
                nouveau->c = i;
     
                /* -ed- ajoute */
                nouveau->suiv = NULL;
     
                printf ("nouveau = %i %c", nouveau->n, nouveau->c);
     
    #if 0
                {
                   /* Cherche la position a inserer */
                   File_carac *tete_tmp = tete;  /* On remet la recherche au debut */
     
                   while (tete_tmp->suiv != NULL && tete_tmp->n <= t[i])
                   {
                      tete_tmp = tete_tmp->suiv;
                   }
                   /* La position est apres tete_tmp, on l'insere donc */
                   printf ("\tinsere a  = %i %c", tete_tmp->n, tete_tmp->c);
                   nouveau->suiv = tete_tmp->suiv;
                   tete_tmp->suiv = nouveau;
                printf ("\tinsere b  = %i %c\n", tete_tmp->suiv->n, tete_tmp->suiv->c);
                }
    #endif
             }
          }
       }
     
       /* -ed-
       Si on retourne l'adresse d'une variable locale, son usage est interdit.
       */
       return tete;
    }
     
    static void AfficherFile (File_carac * tete)
    {
       while (tete != NULL)
       {
          printf ("%i %c\n", tete->n, tete->c);
          tete = tete->suiv;
       }
    }
     
    int main (int argc, char *argv[])
    {
       char nomFichier[250];
     
       printf ("fichier : ");
       /* -ed- retire & (mauvais type)
          foncton difficile a maitriser
          usage dangereux (pas de limitation en entree)
        */
       scanf ("%s", nomFichier);
     
       {
    /* -ed- Suppression 'tTettre' non utilise. */
     
          /* -ed- suppression des casts inutiles. */
          /* Initialisation du tableau t */
          int *t = calloc (256, sizeof (int));
     
          /* -ed- calloc() peut echouer... jamais libere... */
          /* Initialisation du tableau tlettre */
          if (t != NULL)
          {
             int err = occurenceLettre (nomFichier, t);
     
             if (!err)
             {
                afficherTableauLettre (t, 256);
    #if 1
                {
                   File_carac *tete = ConstruireLaFile (t, 256);
                   AfficherFile (tete);
                }
    #endif
             }
             free (t), t = NULL;
          }
       }
       return 0;
    }

Discussions similaires

  1. Une erreur qq part.. Seul le fond s'affiche
    Par Chekov dans le forum OpenGL
    Réponses: 7
    Dernier message: 04/01/2007, 19h27
  2. [VB6] Source D'une erreur
    Par krest dans le forum VB 6 et antérieur
    Réponses: 6
    Dernier message: 16/07/2003, 17h33
  3. [procédure PG] Une erreur mystérieuse...ou pas
    Par doohan dans le forum PostgreSQL
    Réponses: 2
    Dernier message: 09/07/2003, 17h16
  4. Ne pas formater une erreur
    Par Sylvain Leray dans le forum XMLRAD
    Réponses: 2
    Dernier message: 18/03/2003, 14h13

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