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 sur une file


Sujet :

C

  1. #1
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2012
    Messages : 5
    Points : 4
    Points
    4
    Par défaut Erreur de segmentation sur une file
    Bonjour,
    J'essaie de créer une file en c et je bloque à cause d'une erreur que je ne comprend pas.
    Quelqu'un saurait il d'où vient le problème ?

    Voici le code :

    file.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
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    #ifndef FILE_H
    #define FILE_H
     
    typedef struct tagQueueElt{
      int data;
      struct tagQueueElt* next;
    }QueueElt;
     
    typedef struct tagQueue{
      QueueElt* first;
      QueueElt* last;
      int size
    }Queue;
     
    // Initialisation de la file
    void initialization(Queue*);
     
    //Taille de la file
    int size(Queue*);
     
    //Ajout d'un élément dans la file
    int push(Queue*, int);
     
    //Supression du premier élément de la file
    int pop(Queue*);
     
    //Affichage de la liste
    void affiche(Queue*);
     
    #endif
    file.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
    #include <stdlib.h>
    #include <stdio.h>
    #include "file.h"
    
    // Initialisation de la file
    void initialization(Queue* file){
      file->first = NULL;
      file->last = NULL;
      file->size = 0;
    }
    
    //Taille de la file
    int size(Queue* file){
      return file->size;
    }
    
    //Ajout d'un élément dans la file
    int push(Queue* file, int data){
      QueueElt* newelt;
      if ((newelt = (QueueElt*) malloc (sizeof (QueueElt))) == NULL)
        return -1;
     
      newelt->data = data;
    
      QueueElt* courant = file->first;
      if(courant == NULL){
        file->last = newelt;
        newelt->next = file->first;
        file->first = newelt;
      }else{
        if(courant->next == NULL){
          file->last = newelt;
        newelt->next = courant->next;
        courant->next = newelt;
        }
        else{
          file->last->next = newelt;
          newelt->next = NULL;
        }
      }
      file->size++;
      return 0;
    }
    
    
    //Supression du premier élément de la file
    int pop(Queue* file){
      QueueElt* eltsupp;
      if (file->size == 0)
        return -1;
      eltsupp = file->first;
      file->first = file->first->next;
      free(eltsupp);
      file->size--;
      return 0;
    }
    
    
    //Affichage de la liste
    void affiche(Queue* file){
      QueueElt* courant = malloc(sizeof(QueueElt));
      int i;
      courant = file->first;
      
      for(i = 0 ; i < file->size ; i++){
        printf(" %d ", courant->data);
        courant = courant->next;
      }
    }
    Le test
    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
     
    #include <stdlib.h>
    #include <stdio.h>
    #include "file.h"
     
    int main(){
      Queue* file = malloc(sizeof (Queue*));
      printf("taille de file vide : %d\n", size(file));
      push(file,10);
      push(file,20);
      push(file,30);
      push(file,40);
      push(file,50);
      affiche(file);
      printf("\n");
      pop(file);
      affiche(file);
      printf("\n");
    }
    J'obtient 2 erreurs :
    1. file.h:14:1: warning: no semicolon at end of struct or union [enabled by default]
      }Queue;

    1. Erreur de segmentation portant sur le printf(" %d ", courant->data); en gras

    Merci

  2. #2
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Ta fonction push() est vraiment bizarre.
    Par moments j'ai l'impression qu'elle chaîne à l'envers.

    De plus, tu devrais éviter les noms push() et pop() pour une file: Ils sont plus appropriés pour une pile. Tu devrais appeler tes fonctions enqueue() et dequeue() à la place.

    Un bon truc pour éviter les bugs, c'est de faire un fonction qui vérifie l'intégrité de la file. Par exemple, une fonction qui compte les éléments, et vérifie la cohérence avec last et size.

    PS: Pourquoi ta fonction d'affichage fait-elle un malloc()?

  3. #3
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2012
    Messages : 5
    Points : 4
    Points
    4
    Par défaut
    je vois pas ce que tu veux dire "chaine à l'envers".

    Le malloc sert à rien effectivement, mais il ne crée pas d'erreur.

  4. #4
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Après plus de réflexion, j'ai l'impression que ta file est, en fait, circulaire (le dernier élément a son pointeur next qui pointe sur le premier, au lieu d'être nul).
    Y a-t-il une raison à cela?

  5. #5
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2012
    Messages : 5
    Points : 4
    Points
    4
    Par défaut
    C'était pour mettre faire une boucle lorsque la liste est vide (pas une très bonne idée en fait)

  6. #6
    Modérateur

    Avatar de Bktero
    Homme Profil pro
    Développeur en systèmes embarqués
    Inscrit en
    Juin 2009
    Messages
    4 481
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 36
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activité : Développeur en systèmes embarqués

    Informations forums :
    Inscription : Juin 2009
    Messages : 4 481
    Points : 13 677
    Points
    13 677
    Billets dans le blog
    1
    Par défaut
    Quel est ton compilateur ? Parce que le warning pour me semble plutôt est une erreur de syntaxe :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct tagQueue{
      QueueElt* first;
      QueueElt* last;
      int size // il manque le ;
    }Queue;
    As-tu corrigé ce problème pour commencer ?

  7. #7
    Expert éminent sénior
    Avatar de Sve@r
    Homme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Février 2006
    Messages
    12 720
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Oise (Picardie)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : Février 2006
    Messages : 12 720
    Points : 31 037
    Points
    31 037
    Billets dans le blog
    1
    Par défaut
    Citation Envoyé par memedplay Voir le message
    je vois pas ce que tu veux dire "chaine à l'envers".
    Salut
    Comme ton code déborde de commentaires, on a un peu de mal à faire le tri. Et donc ce n'est pas facile de bien voir comment l'élément est "enfilé" dans la file...

    Citation Envoyé par memedplay Voir le message
    Le malloc sert à rien effectivement, mais il ne crée pas d'erreur.
    Ben voyons. Et ce sont les mêmes qui râlent quand un programme consomme trop de mémoire...

    Citation Envoyé par memedplay Voir le message
    Code C : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    typedef struct tagQueue{
      QueueElt* first;
      QueueElt* last;
      int size
    }Queue;
    Ca fait plaisir de voir que tu as pensé à créer un type pour la queue elle-même. Toutefois le mot clef "tagQueue" est inutile. Et si tu nommais ton type "t_Queue" tu serais plus conforme avec les conventions...

    Citation Envoyé par memedplay Voir le message
    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
     
    #include <stdlib.h>
    #include <stdio.h>
    #include "file.h"
     
    // Initialisation de la file
    void initialization(Queue* file){
      file->first = NULL;
      file->last = NULL;
      file->size = 0;
    }
     
    //Taille de la file
    int size(Queue* file){
      return file->size;
    }
     
    //Ajout d'un élément dans la file
    int push(Queue* file, int data){
      QueueElt* newelt;
      if ((newelt = (QueueElt*) malloc (sizeof (QueueElt))) == NULL)
        return -1;
     
      newelt->data = data;
     
      QueueElt* courant = file->first;
      if(courant == NULL){
        file->last = newelt;
        newelt->next = file->first;
        file->first = newelt;
      }else{
        if(courant->next == NULL){
          file->last = newelt;
        newelt->next = courant->next;
        courant->next = newelt;
        }
        else{
          file->last->next = newelt;
          newelt->next = NULL;
        }
      }
      file->size++;
      return 0;
    }
     
     
    //Affichage de la liste
    void affiche(Queue* file){
      QueueElt* courant = malloc(sizeof(QueueElt));
      int i;
      courant = file->first;
     
      for(i = 0 ; i < file->size ; i++){
        printf(" %d ", courant->data);
        courant = courant->next;
      }
    }
    Erreur de segmentation portant sur le printf(" %d ", courant->data); en gras
    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    //Affichage de la liste
    void affiche(Queue* file){
      QueueElt* courant;
      int i;
     
      for (i = 0, courant=file->first ; i < file->size ; i++, courant=courant->next)
        printf(" %d ", courant->data);
    }

    Sinon tu as créé une belle fonction "initialization()". Tu l'utilises quand ???

    Citation Envoyé par memedplay Voir le message
    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
     
    #include <stdlib.h>
    #include <stdio.h>
    #include "file.h"
     
    int main(){
      Queue* file = malloc(sizeof (Queue*));
      printf("taille de file vide : %d\n", size(file));
      push(file,10);
      push(file,20);
      push(file,30);
      push(file,40);
      push(file,50);
      affiche(file);
      printf("\n");
      pop(file);
      affiche(file);
      printf("\n");
    }
    Code c : 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
     
    #include <stdlib.h>
    #include <stdio.h>
    #include "file.h"
     
    int main(){
      Queue file;
      printf("taille de file vide : %d\n", size(&file));
      push(&file,10);
      push(&file,20);
      push(&file,30);
      push(&file,40);
      push(&file,50);
      affiche(&file);
      printf("\n");
      pop(&file);
      affiche(&file);
      printf("\n");
    }

    Ca ne fonctionnera pas mieux mais au-moins ça t'évite
    1. un malloc inutile (pourquoi les gens font un malloc de "1" ça je ne le comprendrai jamais !!!)
    2. d'oublier de le nettoyer après.
    3. et surtout de te vautrer dans ton malloc (ce n'est pas sizeof(Queue*) mais sizeof(Queue) !!!)

    En fait, tout bien réfléchi, peut-être bien que ça fonctionnera en réalité beaucoup mieux...

    Citation Envoyé par memedplay Voir le message
    C'était pour mettre faire une boucle lorsque la liste est vide (pas une très bonne idée en fait)
    Ben non. Te suffit de tester size == 0 pour détecter si ta liste est vide ou pas. Parce que boucler sur soi-même ça peut vite devenir synonyme de boucle infinie...

  8. #8
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Toutefois le mot clef "tagQueue" est inutile. Et si tu nommais ton type "t_Queue" tu serais plus conforme avec les conventions...
    En fait, typedef struct tagXXXXX { ... } XXXXX; est une convention, qui est utilisée pour pratiquement toutes les structures sous Windows...

  9. #9
    Candidat au Club
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2012
    Messages
    5
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2012
    Messages : 5
    Points : 4
    Points
    4
    Par défaut
    Merci à tous!

  10. #10
    Expert éminent sénior
    Avatar de Médinoc
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Septembre 2005
    Messages
    27 379
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Septembre 2005
    Messages : 27 379
    Points : 41 573
    Points
    41 573
    Par défaut
    Mon conseil principal: Enlève la circularité, et fais une fonction de vérification que tu appelles au début et la fin de chaque fonction (du moins, dans la version de débogage).
    Code C : 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
    void Verifier(Queue const *file)
    {
    	if(file == NULL) {
    		puts("Rien à vérifier (NULL)");
    		return;
    	}
     
    	/*Si la file est vide, tout est à NULL et zéro.
    	  Si elle n'est pas vide, rien n'est à NULL ou zéro.*/
    	if(file->first==NULL && file->last==NULL && file->size==0) {
    		puts("OK (file vide, cohérente).");
    		return;
    	}
    	if(file->first==NULL || file->last==NULL || file->size==0) {
    		puts("Incohérence! La file est à moitié vide.");
    		return;
    	}
     
    	/*Parcoure la chaîne, vérifie le dernier élément et le nombre*/
    	{
    		int nbFound = 0;
    		QueueElt const *current;
    		QueueElt const *lastFound = NULL;
    		for(current = file->first ; current != NULL ; current = current->next) {
    			lastFound = current;
    			/*Quitte au bout de deux éléments de plus que size*/
    			if(nbFound > file->size) {
    				printf("Trop d'éléments trouvés (déjà %d au lieu de %d), on quitte pour éviter une boucle infinie.\n", nbFound+1, file->size);
    				break;
    			}
    			nbFound++;
    		}
    		if(lastFound != file->last)
    			puts("Incohérence sur dernier élément.");
    		if(nbFound != file->size)
    			puts("Incohérence sur nombre d'éléments.");
    	}
    }
    Je n'ai pas testé, ni même compilé, mais c'est à ça que devrait ressembler la fonction de vérification.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XPATH 1.0] Erreur de segmentation sur une requête programmée en C avec libxml2
    Par BabzIm dans le forum XSL/XSLT/XPATH
    Réponses: 4
    Dernier message: 26/05/2015, 16h28
  2. Erreur de segmentation sur une concaténation
    Par cypher.sephiroth dans le forum Débuter
    Réponses: 14
    Dernier message: 18/08/2009, 17h42
  3. Erreur de segmentation sur une File
    Par hugo1992 dans le forum C
    Réponses: 2
    Dernier message: 22/10/2007, 08h49
  4. erreur PLS-00103 sur une fonction
    Par atruong dans le forum Oracle
    Réponses: 2
    Dernier message: 28/04/2006, 13h49
  5. Erreur de segmentation sur une chaine en récursif...
    Par laurent_ifips dans le forum C
    Réponses: 12
    Dernier message: 13/12/2005, 16h04

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