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, encore une


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 4
    Par défaut Erreur de segmentation, encore une
    Bonjour à tous,
    voilà je me creuse depuis un moment deja sur une erreur de segmentation que je ne comprend pas.

    En gros, j'ai un fichier que je parse, je recupere les données dans des variables, et je veux les stocker dans une structure. Ma structure est celle-là :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    struct process{
     
    	int pid;
    	int pidPere;
    	char *user;
    	char *nomCommande;
    };
     
    typedef struct process PROCESS;
    Et mon code :

    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
     
    GNode *creeArbre(char *Chaine){
     
    	PROCESS *pProc;
    	pProc = (PROCESS *)malloc(sizeof(PROCESS));
    	GNode *noeud;
    	GNode *racine;
     
            FILE *fp = NULL;
     
    	if((fp=fopen(Chaine,"r"))==0){
       		menu(); /*retour menu*/
    	}
     
    	fgets(ligne,LONG,fp);/*up la premiere ligne*/
     
    	while (fgets(ligne,LONG,fp) != 0){
    		sscanf(ligne,"%s %d %d %d %s %s %s %s", pUser, &pid, &ppid, &c, stime, tty, time, pNomCommande);
    		pProc->user = pUser;	 /*C'est là que ca merde*/
    		pProc->pid = pid;
    		pProc->pidPere = ppid;
    		pProc->nomCommande = pNomCommande; 
    		g_node_insert( g_node_find_pid(racine,pProc->pidPere),-1,g_node_new(pProc));*/
    	}
    Mon sscanf me recupere bien toutes les données, mais l'affectation dans le champ de la structure loupe. Le plus étrange, c'est que si je fais l'affectation avant la boucle while, elle fonctionne, mais si je l'a fait dedans ou apres, non.

    Alors je ne sais pas si ca peut venir du sscanf, parce que quand j'affiche ce que j'ai recuperé, c'est bon...

  2. #2
    Membre émérite
    Avatar de D[r]eadLock
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    504
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 504
    Par défaut
    Citation Envoyé par LCoileux Voir le message
    Alors je ne sais pas si ca peut venir du sscanf, parce que quand j'affiche ce que j'ai recuperé, c'est bon...
    Ce n'est pas parce que ce qui est affiché est correct, que le code l'est ;D

    Il n'y a pas la déclaration des pointeurs donné à sscanf (pUser, ...). Ces pointeurs sont-ils alloués ? À quelle taille ? Car ce qui est douteux est qu'il n'y a pas de limite sur les %s. Tu peux utiliser valgrind pour voir si tu ne fait pas des trucs "louches".
    En plus, dans ta boucle tu va faire pointer user et nomCommande sur une même adresse.

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 4
    Par défaut
    C'est vrai que je n'ai pas mis mes declarations, j'ai jugé inutile de les poster car (a mon avis) ca ne vient pas de là...
    En tout cas, les voilà :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    #define LONG 1000
     
    char stime[LONG],tty[LONG],time[LONG], pUser[LONG], pNomCommande[LONG], ligne[LONG];
    int pid,ppid,c;
    Comme debuggueur j'ai utilisé ddd, celui-ci me disait que l'erreur venait de sscanf mais je ne vois pas pourquoi.

  4. #4
    Membre Expert
    Profil pro
    Inscrit en
    Août 2006
    Messages
    1 104
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Août 2006
    Messages : 1 104
    Par défaut
    Salut

    Ton code est blindé de globales. Elles ne sont absolument pas justifiées... et ça rend le debuggage encore plus compliqué, vu qu'on ne peut plus vraiment savoir qui modifie quoi.

    Y a un truc qui me surprend dans ton code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    if((fp=fopen(Chaine,"r"))==0){
    	menu(); /*retour menu*/
    }
     
    fgets(ligne,LONG,fp);/*up la premiere ligne*/
    (...)
    Lorsque tu appelles la fonction menu en cas d'échec de fopen, tu provoques bien un appel... pas un saut. Lorsque la fonction menu se termine, l'exécution du code reprend juste après l'appel de cette fonction, c'est-à-dire en faisant crasher fgets, vu que fp est égal à NULL...

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mai 2010
    Messages
    4
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2010
    Messages : 4
    Par défaut
    Ah merde, j'ai oublié le else, quel ***
    Mais en fait, ma fonction menu attend une entrée de ma part, du coup c'est pas sur que je revienne dans cette partie du code. A moins qu'elle y reviendra quand meme ?

    Pour les globales, je n'etais pas vraiment sur de pouvoir remplir directement les champs de ma structure avec sscanf, donc dans le doute j'ai preféré passer par ca.

  6. #6
    Expert confirmé
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Par défaut
    De toute façon, ceci va provoquer des trucs baroques :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
      pProc->user = pUser;	 /*C'est là que ca merde*/
    ....
      pProc->nomCommande = pNomCommande;
    Il y a recopie de l'adresse des tableaux pUser et pNomCommande, pas recopie de leur contenu (d'ailleurs, il n'y a pas de place dans la structure pour stocker une copie).
    Comme on utilise toujours les deux mêmes tableaux, toutes les structures stockeront les mêmes adresses et pointeront donc vers les deux mêmes chaines, à savoir les dernières lues.

  7. #7
    Membre émérite
    Avatar de D[r]eadLock
    Profil pro
    Inscrit en
    Mai 2002
    Messages
    504
    Détails du profil
    Informations personnelles :
    Âge : 45
    Localisation : France

    Informations forums :
    Inscription : Mai 2002
    Messages : 504
    Par défaut
    Bon, reprenons (avec les remarques de jeroman et diogène), pour essayer d'y voir plus clair:
    • la valeur de retour du malloc n'est pas vérifiée
    • il y trop globales et c'est mal(tm)
    • pProc n'est alloué qu'une seule fois, alors qu'il semblerait qu'il faille insérer plusieurs entrées dans l'arbre
    • racine n'est pas déclaré (y'a pas de warnings la dessus ?, ou code manquant ?)
    • le code du premier fgets n'est pas testé
    • le code de retour du sscanf n'est pas testé
    • les données parsées ne sont pas dupliquées (pProc->nomCommande = strdup(...))
    • les codes de retour de g_node_{insert,find_pid,new} ne sont pas testés
    • le protoype devrait sûrement être GNode *creeArbre(const char *Chaine)
    • si le test de l'ouverture échoue, on continue au lieu de s'arrêter (un return NULL serait pas mal)
    • fgets renvoie un pointeur, ce serait bien de le tester avec NULL (et non 0)
    • time et stime sont des fonctions de la libc, ce serait bien d'éviter d'utiliser leur nom
    • code manquant ?:
      • noeud n'est pas utilisé
      • il y a un */ qui traîne
      • pas de fclose(fp)



    Maintenant, une fois que ceci sera corrigé , quelques informations complémentaires permettraient d'avancer si le problème est toujours présent:
    - cela se produit-il au premier passage de boucle ?
    - sinon, quand ? Sur une ligne particulière ?
    - je persiste à penser que valgrind pourrait t'aider si tu fais de mauvaise choses en mémoire; les effets ne sont pas visible tout de suite et le programme peut ne pas planter ou planter à un endroit tout à fait différent de là où est l'erreur.

Discussions similaires

  1. Erreur de segmentation sur une concaténation
    Par cypher.sephiroth dans le forum Débuter
    Réponses: 14
    Dernier message: 18/08/2009, 17h42
  2. Réponses: 1
    Dernier message: 11/03/2009, 15h09
  3. Erreur de segmentation (encore. . .)
    Par WaKaaN dans le forum Débuter
    Réponses: 6
    Dernier message: 22/10/2008, 15h22
  4. Erreur de segmentation sur une File
    Par hugo1992 dans le forum C
    Réponses: 2
    Dernier message: 22/10/2007, 08h49
  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