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


Sujet :

C

  1. #1
    Membre régulier
    Inscrit en
    Mai 2008
    Messages
    146
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 146
    Points : 81
    Points
    81
    Par défaut Erreur de segmentation
    Bonjour a tous,

    Je m excuse a l avance, je suis sur un clavier US et je ne vois pas les accents donc pardon pour ma ponctuation desastreuse.

    Comme le dit le titre, je bloque sur une erreur de segmentation dont voici le 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
    25
    26
    27
    28
    void lire(int num){
    // PROBLEME : CB Y A TIL DE FICHIERS DS LE DOSSIER AFIN DE COMPARER AVEC NUM --->  nbfiles()
    // PB2 : Segmentation fault ?
    	int cmp = nbfiles("home/larchicha/Desktop/recus");
    	int i ; int descript ;
    	char * num_str = malloc(50*sizeof(char)); 
    	char * buff = malloc(100*sizeof(char)); 
    	char * chemin = malloc(100*sizeof(char));;
    	strcpy(chemin,"home/larchicha/Desktop/recus/");// chemin contient le debut du chemin moins le nom du fichier (1 2 3 4)
    	for(i=0;i<cmp;i++){
    		if (i == num){// tant qu on trouve pas le numero du symlink on boucle
    			snprintf(num_str, 4, "%d", num);// convertit num : int -> string
    			strcat(chemin,num_str);// concat le nom du fichier (1 ou 2 ou 3 ou 4) au chemin
     			descript = open(chemin,O_RDONLY);//on ouvre le fichier appeller 'num' 
    			read(descript,buff,sizeof buff);// on lit le contenu du fichier
    			printf("Le contenu du message est : %s\n",buff);//on l affiche
    		} else {
    		//perror("Le numero donne en argument ne correspond a aucun fichier : ");
    		}
    	}
    }
     
    int main(){
     
    	nbfiles("recus");
    	lire(2);
    	return 0;
    }
    A savoir que la fonction nbfiles(const char *) prend le chemin d un repertoire et me renvoi le nombre de fichiers au il contient. (elle fonctionne, je l ai testee dans un autre fichier)

    J ai bien entendu essaye de mettre en commentaire toutes les lignes qui me semblait potentiellement fausse mais je coince.

    Merci pour l aide apportee.

  2. #2
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    1 186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 186
    Points : 2 502
    Points
    2 502
    Par défaut
    Bonjour,

    Je vois 2 problèmes potentiels :
    - ligne 15 : sizeof buff, ne retourne pas la taille de la mémoire allouée par le malloc, mais l'équivalent de sizeof (char *).
    (la taille de la mémoire alloué pour un pointeur).

    -ligne 16 : printf (.."%s", buff); ici rien ne garanti que buff se termine pas le caractère de fin de chaîne \0 .
    Par conséquent, il est tout à fait possible que printf cherche à accéder à de la mémoire non allouée.

    Enfin je recommande, de :
    - vérifier que la fonction open(..) ne retourne pas -1, indiquant un problème à l'ouverture de fichier.
    - fermer les fichiers ouverts avec la fonction close()

  3. #3
    Membre régulier
    Inscrit en
    Mai 2008
    Messages
    146
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 146
    Points : 81
    Points
    81
    Par défaut
    Merci de ta promptitude, je vais verifier de suite.

  4. #4
    Membre régulier
    Inscrit en
    Mai 2008
    Messages
    146
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 146
    Points : 81
    Points
    81
    Par défaut
    J ai corrige mais l erreur reste toujours presente.
    Etant donne que j ai besoin du print je l ai juste mis en commentaires et l erreur est restee.

    Perso je pense plus a strcpy et strcat pour l erreur ( impression de deja vu).

    Merci encore pour l aide apportee.

  5. #5
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    1 186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 186
    Points : 2 502
    Points
    2 502
    Par défaut
    Comme ça je ne vois pas d'erreur sur la partie strcat ou strcpy.
    Par contre vérifie que open() a fonctionné en testant descript soit différent de -1.
    (parce qu'il n'y a jamais de close ... Et par conséquent il est possible que les fichiers soient restés ouvert, ce qui ferait échouer une nouvelle ouverture).

  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 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Tu devrais rajouter des vérifications des allocations dynamiques.

  7. #7
    Membre régulier
    Inscrit en
    Mai 2008
    Messages
    146
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 146
    Points : 81
    Points
    81
    Par défaut
    Je teste au fur et à mesure mais toujours la même erreur.

    Sinon, une question comme ça... Pour qu'une allocation dynamique plante, y'a une chance sur 1000 nan ?

  8. #8
    Membre régulier
    Inscrit en
    Mai 2008
    Messages
    146
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 146
    Points : 81
    Points
    81
    Par défaut
    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
    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <sys/stat.h>
    #include <string.h>
    #include <fcntl.h>
    #include <dirent.h>
    #define PATH "home/larchicha/Desktop/recus"
     
     
    void lire(int num){
    // PROBLEME : CB Y A TIL DE FICHIERS DS LE DOSSIER AFIN DE COMPARER AVEC NUM ___> FUCK YOU grace a nbfiles()
    // PB2 : Segmentation fault ?
    	int cmp = nbfiles("home/larchicha/Desktop/recus");
    	int i ; int descript ;
    	char * num_str = malloc(50*sizeof(char)); 
    	if (num_str != NULL){
    		char * chemin = malloc(100*sizeof(char));
    		if (chemin != NULL){
    			strcpy(chemin,"home/larchicha/Desktop/recus/");// chemin contient le debut du chemin moins le nom du fichier (1 2 3 4)
    			for(i=0;i<cmp;i++){
    				if (i == num){// tant qu on trouve pas le numero du symlink on boucle
    					snprintf(num_str, 4, "%d", num);// convertit num : int -> string
    					strcat(chemin,num_str);// concat le nom du fichier (1 ou 2 ou 3 ou 4) au chemin
    		 			descript = open(chemin,O_RDONLY);//on ouvre le fichier appeller 'num' 
    					if (descript != -1) {
    						char * buff = ""; 
    						read(descript,buff,100);// on lit le contenu du fichier
    						//printf("Le contenu du message est : %s\n",buff);//on l affiche
    					} else {
    						perror("Erreur d ouverture du fichier : ");
    					}
    				} else {
    					perror("Le numero donne en argument ne correspond a aucun fichier : ");
    				}
     
    			}
    		}
    	}
    	close(descript);
     
    }	
     
    int main(){
     
    	nbfiles("recus");
    	lire(4);
    	return 0;
    }
    Toujours a l execution : Segmentation Fault

  9. #9
    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 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    char * buff = "";
    read(descript,buff,100);// on lit le contenu du fichier
    Pourquoi le pauvre buff n'a pas le droit à un malloc ?

    Sinon, une question comme ça... Pour qu'une allocation dynamique plante, y'a une chance sur 1000 nan ?
    J'ai jamais eu de problème avec malloc mais je n'ai jamais fait de programmes vraiment gros avec des allocations vraiment grosses. Tu peux lire ça pour plus d'information.

  10. #10
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    1 186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 186
    Points : 2 502
    Points
    2 502
    Par défaut
    Bonsoir,

    Effectivement dans la dernière version du code, il n'y a plus de mémoire allouée.
    Pire on lui fait prendre l'adresse de "".

    Sinon en règle générale (ceci n'est pas à l'origine du bug), on utilise la pile en créant des variables automatiques
    afin de ne pas avoir à gérer l'allocation / dé-allocation de mémoire.
    (Et oui, à un malloc doit normalement correspondre un free ici oublié)

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    void f()
    {
       char buff[100]; // variable automatique, mémoire alloué dans la pile
                            // et dé-alloué automatiquement à la fin de la fonction
     
       char * pbuff = malloc ( 100 * sizeof (char));   // pointeur sur mémoire allouée dynamiquement dans le tas.
                            // la mémoire ne sera PAS libéré automatiquement à la fin de la fonction.
     
       free(pbuff);    // libère la mémoire allouée avec malloc.
     
    }
    Sinon pour aider à localiser le problème, (si le débugger ne précise pas la ligne où survient le problème,
    et l'exécution en pas à pas n'est pas possible, essaye de mettre des sorties indiquant la progression d'execution du programme.
    (à l'affichage avec printf ou dans un fichier de log fprintf).

  11. #11
    Membre régulier
    Inscrit en
    Mai 2008
    Messages
    146
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 146
    Points : 81
    Points
    81
    Par défaut
    Merci de vos reponses... je test tout ca en rentrant.

  12. #12
    Membre régulier
    Inscrit en
    Mai 2008
    Messages
    146
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 146
    Points : 81
    Points
    81
    Par défaut
    Ne m'en sortirais je donc jamais ?
    Apres les corrections, toujours la meme erreur de segmentation...

    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
    void lire(int num){
    // PROBLEME : CB Y A TIL DE FICHIERS DS LE DOSSIER AFIN DE COMPARER AVEC NUM ___> FUCK YOU grace a nbfiles()
    // PB2 : Segmentation fault ?
    	int cmp = nbfiles("home/larchicha/Desktop/recus");
    	int i ; int descript ;
    	char * num_str = malloc(50*sizeof(char)); 
    	if (num_str != NULL){
    		char * chemin = malloc(100*sizeof(char));
    		if (chemin != NULL){
    			strcpy(chemin,"home/larchicha/Desktop/recus/");// chemin contient le debut du chemin moins le nom du fichier (1 2 3 4)
    			for(i=0;i<cmp;i++){
    				if (i == num){// tant qu on trouve pas le numero du symlink on boucle
    					snprintf(num_str, 4, "%d", num);// convertit num : int -> string
    					strcat(chemin,num_str);// concat le nom du fichier (1 ou 2 ou 3 ou 4) au chemin
    		 			descript = open(chemin,O_RDONLY);//on ouvre le fichier appeller 'num' 
    					if (descript != -1) {
    						char * buff = malloc(100*sizeof(char)); 
    						 if (buff != NULL){
    							read(descript,buff,100);// on lit le contenu du fichier
    							printf("Le contenu du message est : %s\n",buff);//on l affiche
    						}
    						free(buff);
    					} else {
    						perror("Erreur d ouverture du fichier : ");
    					}
     
    				} else {
    					perror("Le numero donne en argument ne correspond a aucun fichier : ");
    				}
     
     
    			}
    		}
    		free(chemin);
     
    	}
    	close(descript);
     
    	free(num_str);
    }
     
    int main(){
     
    	nbfiles("recus");
    	lire(4);
    	return 0;
    }
    Par ailleurs, le but de cette fonction me permet de lire un fichier dont le nom est "num" donc si vous pensez a un code plus simple, ne vous genez pas...
    Merci du temps alloue a mon probleme

  13. #13
    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 679
    Points
    13 679
    Billets dans le blog
    1
    Par défaut
    Le problème pour t'aider est que ton code n'est pas compilable...

    As-tu essayé au moins réussi à savoir quelle ligne provoque l'erreur (à l'aide printf pour connaitre l'avancement ou, mieux, avec un débogueur ?)

  14. #14
    Membre régulier
    Inscrit en
    Mai 2008
    Messages
    146
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 146
    Points : 81
    Points
    81
    Par défaut
    T'as raison, a force de trop bloquer j'ai tendance a trop compter sur vous.
    Demain, je me ferais tous les printf et on verra bien.

    Merci.

  15. #15
    Membre émérite
    Homme Profil pro
    Inscrit en
    Décembre 2011
    Messages
    1 186
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Décembre 2011
    Messages : 1 186
    Points : 2 502
    Points
    2 502
    Par défaut
    Bonjour,

    Dans la portion de code lignes 18 à 20, je vois un problème signalé précédemment non géré :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    if (buff != NULL)
    {
              read(descript,buff,100);// on lit le contenu du fichier
    	  printf("Le contenu du message est : %s\n",buff);//on l affiche
    }
    - la fonction read ne garantie pas que la chaîne de caractère se termine par un caractère de fin de chaîne.
    Du coup le printf peut chercher à lire plus de 100 caractères à partir de l'adresse buff
    - Le nombre max de char relu par la fonction read est de 100 char.
    Si on relit 100 char, il ne restera plus de place pour ajouter le caractère de fin de chaîne.

    Du coup je transformerais ça en :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    if (buff != NULL)
    {
              int nbByteRead = read(descript,buff,99);// on lit le contenu du fichier
              if (nbByteRead >= 0)
              {
                   buff[nbByteRead] = '\0';
    	       printf("Le contenu du message est : %s\n",buff);//on l affiche
              }
    }
    Ca n'est peut être pas l'origine du problème, mais ça ne peut pas faire de mal.

  16. #16
    Membre régulier
    Inscrit en
    Mai 2008
    Messages
    146
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 146
    Points : 81
    Points
    81
    Par défaut
    Très bon ça ! J'avais completement zappé...

    Bizarrement, en rebootant VMWARE et a fortiori ma session...
    En recompilant j'ai eu un tas d'erreurs concernant les headers que j'avais inclus...

    Rien de bien méchant j'espère, mais en tout cas, merci de ton implication

  17. #17
    Membre régulier
    Inscrit en
    Mai 2008
    Messages
    146
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 146
    Points : 81
    Points
    81
    Par défaut
    Bon pardon, le sujet traîne pas mal....

    Malgré toutes vos corrections, j'ai toujours la même erreur, "Segmentation Fault".

    J'ai tenté de tout commenter donc un programme vide et pourtant toujours la meme erreur !

    Désolé du coup de gueule mais ca fait quelques jours et toujours pas d'avancement.

  18. #18
    Membre éclairé
    Avatar de Kirilenko
    Homme Profil pro
    Étudiant
    Inscrit en
    Décembre 2011
    Messages
    234
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 27
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Décembre 2011
    Messages : 234
    Points : 807
    Points
    807
    Par défaut
    La meilleure manière de déceler une erreur de segmentation est d'utiliser un débogueur (par exemple valgrind) afin de trouver la ligne fautive (après une compilation nécessitant le flag -g). Cela nous permettra de mieux cerner ton problème.
    Récursivité en C : épidémie ou hérésie ?

    "Pour être un saint dans l'Église de l'Emacs, il faut vivre une vie pure. Il faut se passer de tout logiciel propriétaire. Heureusement, être célibataire n'est pas obligé. C'est donc bien mieux que les autres églises" - Richard Stallman

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