un segementation fault a cause d'un fclose???

un segementation fault a cause d'un fclose??? - C - Programmation

Marsh Posté le 04-04-2008 à 12:00:07    

Bonjour,
 
Dans mon demineur lorsque j'essaie de lire un fichier depuis le terminal en tapant ./edit -f nom_fichier.txt
il ne veut pas me lancer mon jeu car j'ai un segmentation fault du un fclose() que j'ai pu voir a l'aide du gdb mais j'ai tout essayé enfin tout ce que je sais mais je n'arrive pas a voir d'ou viens le soucis j'aurais besoin d'un serieu coup de main MERCI a vous voici le code ou cela bug:
 
champs lire(char *fichier){
  int nb_ligne,nb_colonnes,nb_erreur_restant,k;
  int nb_mine=0;
  champs C;
  char p;
  FILE *flot;
   
  nb_mine=nb_mine_fichier(fichier);
  flot=fopen(fichier,"r" );
   
  if(flot==NULL){
    printf("erreur lors de l'ouverture du fichier %s",fichier);
    return NULL;
  }
  fscanf(flot," %i %i %i",&nb_ligne,&nb_colonnes,&nb_erreur_restant);//je lis la premiere ligne de mon fichier
  C=init(nb_ligne,nb_colonnes,nb_mine,nb_erreur_restant);
  if(C==NULL){
    printf("l'initialisation n'a donc pas eu lieu\n" );
    return NULL;
  }
  p=getc(flot);
  k=0;
  while(p!=EOF){//je lis caractere par caractere
    if(p!=' ' && p !='\n'){
       
      switch(p){// je modifie dans le switch mon champs C
      case '*':C->tab[k].mine=0;C->tab[k].status=PASVU;
 break;
      case 'N':C->tab[k].mine=1;C->tab[k].status=PASVU;
 break;  
      case '-':C->tab[k].mine=0;C->tab[k].status=DEJAVU;
 break;
      case 'M':C->tab[k].mine=1;C->tab[k].status=DEJAVU;
 break;
      default: break;
      }
      k++;
    }
    p=getc(flot);
     
  }
  if(C==NULL)
    printf("soucis" );
   
  fclose(flot);//le souci vien de la  
  return C;
   
}
 
 
Merci a vous
 

Reply

Marsh Posté le 04-04-2008 à 12:00:07   

Reply

Marsh Posté le 04-04-2008 à 13:25:15    

getc retourne un int, pas un char. D'où overflow sur la donnée suivante qui est *flot.
Par ailleurs, même si getc() égal à fgetc(), il serait plus cohérent d'utiliser fgetc().


Message édité par olivthill le 04-04-2008 à 13:26:31
Reply

Marsh Posté le 04-04-2008 à 13:30:24    

oui c'est vrai c'est ce que j'avais fait au debut mais cela ne change rien j'ai la meme erreur:
 
#14 0xb7ea813a in _IO_file_overflow () from /lib/tls/i686/cmov/libc.so.6
#15 0xb7eb1800 in free () from /lib/tls/i686/cmov/libc.so.6
#16 0xb7e9c6f4 in fclose () from /lib/tls/i686/cmov/libc.so.6

Reply

Marsh Posté le 04-04-2008 à 14:04:01    

De quelle manière cela avait été fait, et est-ce que la modification portait sur tous les endroits où getc() est appellée ?
Par ailleurs, toujours par soucis de cohérence avec la série des fonctions fxxxxx, au lieu de EOF on utilise habituellement feof().

Reply

Marsh Posté le 04-04-2008 à 15:04:15    

À mon avis, vérifie que k ne dépasse pas les bornes du tableau C->tab. Ça devrait résoudre ton problème.
 
Edit: d'ailleurs on pourrait voir la fonction init() ?


Message édité par tpierron le 04-04-2008 à 15:05:14
Reply

Marsh Posté le 04-04-2008 à 19:46:39    

Ca peut être du à un écrasement mémoire.
 
Vérifie déjà si ton pointeur FILE * est le même à l'inititialisation et quand tu fais ton fclose().

Reply

Marsh Posté le 05-04-2008 à 01:37:07    

Merci pour vos réponses alors tout d'abord j'ai modifié mon test de la boucle while et j'ai mis un feof() puis j'ai vérifié si k dépassé les bornes et non k vaut s bien pour 10 lignes et 10 colonnes ->> 99 et enfin l'idée de l'écrasement mémoire me parait bonne car j'ai meme changer la maniere d'appeler la fonction le champs C est initialisé sans soucis mais lorsque j'arrive a fclose() la j'ai un segmentation fault donc xilebo comment puis je voir concrétement si le pointeur FILE * est le meme lors de l'initialisation et lors du fclose() si c'est a l'aide du gdb et je fait un b flot et je compare l'adresse ceci a été fait et le résultat:
j'ai la meme adresse lors du fopen() et apres le fclose()
est ce normal?
avez vous d'autres idées .
Merci

Reply

Marsh Posté le 05-04-2008 à 03:09:17    

J'ai trouvé d'ou viens le soucis je pense que c'est la version de gcc qui n'est pas bonne car quand je met sous vista avec cygwin je n'ai pas d'erreur ni de segmentation fault mais sur ubuntu 7.10 j'ai un segmentation fault.
Si il y a quelqu'un qui peut m'aider sur ca, ca serait bien.
Merci

Reply

Marsh Posté le 05-04-2008 à 08:43:48    

Non non, ce n'est pas un problème du à gcc mais une erreur de ta part, forcément :) Un bug d'écrasement de mémoire est intempestif, selon le compilateur et l'OS , il pourra ou non arriver, mais le bug est toujours là.
 
Si ton code n'est pas trop gros, essaie de le poster en entier, ça permettra de voir où est le problème.
 
Et ta méthode de lecture dans un fichier n'est pas bonne. Généralement, il vaut mieux lire chaque ligne de ton fichier avec la fonction fgets, qui retourne NULL en cas de fin de fichier ou d'erreur. Voir la doc avec man fgets. Ensuite, tu n'as qu'à faire un sscanf sur ton buffer pour récuperer tes données.

Reply

Marsh Posté le 05-04-2008 à 12:00:25    

olivthill a écrit :

Par ailleurs, toujours par soucis de cohérence avec la série des fonctions fxxxxx, au lieu de EOF on utilise habituellement feof().


Absolument pas. Malgré son nom (et ceci a déjà été dit maintes et maintes fois sur ce fofo), la fonction feof() ne détecte pas la fin de fichier. Son but est de détecter si, une fois que le fichier ne peut plus être lu, si la "non-lecture" est due à une fin de fichier ou autre chose (erreur par exemple). Cela entraine que quand on arrive à la fin de fichier, la fonctio feof() renvoie faux et l'algo effectue une lecture de trop
 
Exemple

Code :
  1. #include <stdio.h>
  2. int main()
  3. {
  4.    FILE *fp;
  5.    int c;
  6.    fp=fopen("/etc/passwd", "r" );
  7.    while (!feof(fp))
  8.         printf("Caractère lu: %c\n", fgetc(fp));
  9.    fclose(fp);
  10. }


L'algo bouclera une fois de trop
 

xilebo a écrit :


Et ta méthode de lecture dans un fichier n'est pas bonne. Généralement, il vaut mieux lire chaque ligne de ton fichier avec la fonction fgets, qui retourne NULL en cas de fin de fichier ou d'erreur. Voir la doc avec man fgets. Ensuite, tu n'as qu'à faire un sscanf sur ton buffer pour récuperer tes données.


C'est au choix du programmeur. C'est vrai que lire une ligne d'un coup va plus vite mais il a le droit de lire caractère par caractère.
Cependant, au lieu de faire comme en COBOL, et écrire

Code :
  1. lire un caractère
  2. tant que not EOF
  3. FAIRE
  4.        traitement
  5.        lire caractère
  6. FIN FAIRE


 
Le C permet d'écrire

Code :
  1. tant que caractère lu différent EOF
  2. FAIRE
  3.        traitement
  4. FIN FAIRE


 
Ce qui se traduit par

Code :
  1. while ((p=fgetc(flot)) != EOF)
  2. {
  3.     <... traitement ...>
  4. }


 
Sinon pour en revenir au problème que je prends en cours de route, ce qui m'inquiète c'est ce fscanf() qui précède  la lecture. Déjà étant donné que la lecture elle-même est malhabile, je me demande comment l'ordi réagit avec ce fscanf() placé un peu avant...
 
 


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 05-04-2008 à 12:00:25   

Reply

Marsh Posté le 05-04-2008 à 16:10:53    

oui surement c'est du au fscanf l'idée d'utiliser un fgets et un sscanf me parait pas mal je vais essayer mais la fonction sscanf je ne la connais pas comment s'utilise t elle et que fait elle exactement.
Merci.

Reply

Marsh Posté le 05-04-2008 à 16:47:05    

J'ai remarquer quelque chose de bisar lorsque je fait le gdb pour voir ou j'ai le segmentation fault c'est lorsque j'arrive a l'endroit ou je fait C=init...  
que sur le terminal il y a ecrit ce que je demande de faire avant de rentrer dans cette fonction   .
Je fais ca :
printf("%s yooooooo",argv[2]);
      test=lire(argv[2]);
 
et dans mon gdb il est affiché que lorsque j'arrive a la ligne C=init c'est louche non?
(au passage la methode avec le fgets() et sscanf() ne fonctionne pas j'ai toujours un segmentation fault du au fopen() mais avec un autre message c'est le suivant:
#0  0xb7e03a8b in ?? () from /lib/tls/i686/cmov/libc.so.6
#1  0xb7f0d668 in ?? ()
#2  0x080483f6 in ?? ()
#3  0xfd09cf21 in ?? ()
#4  0x00000000 in ?? ()

Reply

Marsh Posté le 05-04-2008 à 17:28:23    

Mon petit doigt me dit que ta fonction init() fait n'importe quoi. À quand le source ?

Reply

Marsh Posté le 05-04-2008 à 18:18:50    

la fonction init() ne fait pas n'importe quoi je l'ai testé jai meme suivi etape par etape ce quel fesait et meme apres init() lorsque je teste le champs jai bien ce que je voulais , le soucis viens du fclose() mais je n'ai aucune idée du pourquoi et du comment.
Au pire donnez moi silvou plait une idée pour sauvegarder l'état du demineur, moi ce que je fait c'est en premiere ligne le nombre de lignes, de colonnes et le nombre erreurs qui restent et apres selon mon champs je met une etoile un tiret un M ou un N .
Merci a vous.

Reply

Marsh Posté le 05-04-2008 à 19:44:28    

C'est bonnnnnnnnnnnnnnnnn j'ai reussi a trouver le soucis en fait cela venait du fclose() a la fin il fallait pas le mettre avant le return C mais apres c'est a dire apres avoir quitter la fonction a l'endroit ou je l'ai appelé jai fait un fclose((flot=fopen(nom_fic,"r" ));
et maintenant sa marche nickel.
Merci a vous quand meme.
A bientot peut etre bye

Reply

Marsh Posté le 05-04-2008 à 20:35:20    

zizouuuu a écrit :

mais la fonction sscanf je ne la connais pas comment s'utilise t elle et que fait elle exactement.


scanf() récupère des valeurs dans stdin (on va dire "le clavier" pour pas t'effrayer avec des mots trop complexes) alors que sscanf() récupère des valeurs dans la chaine qu'on lui passe en premier paramètre
 

zizouuuu a écrit :

C'est bonnnnnnnnnnnnnnnnn j'ai reussi a trouver le soucis en fait cela venait du fclose() a la fin il fallait pas le mettre avant le return C mais apres c'est a dire apres avoir quitter la fonction a l'endroit ou je l'ai appelé jai fait un fclose((flot=fopen(nom_fic,"r" ));


T'es trop un winner toi !!!
Le C c'est comme les poupées russes. Ce que ta fonction fait, elle doit le défaire. Si ta fonction fait un fopen(), alors ensuite elle doit faire un fclose(). Là, tu fais juste "fermer(ce que j'ouvre)"
 

zizouuuu a écrit :

A bientot peut etre bye


A mon avis ce sera bien plus tôt que tu ne le crois...


---------------
Vous ne pouvez pas apporter la prospérité au pauvre en la retirant au riche.
Reply

Marsh Posté le 06-04-2008 à 17:18:47    

zizouuuu a écrit :

C'est bonnnnnnnnnnnnnnnnn j'ai reussi a trouver le soucis en fait cela venait du fclose() a la fin il fallait pas le mettre avant le return C mais apres c'est a dire apres avoir quitter la fonction a l'endroit ou je l'ai appelé jai fait un fclose((flot=fopen(nom_fic,"r" ));
et maintenant sa marche nickel.
Merci a vous quand meme.
A bientot peut etre bye


n'hésite pas à revenir nous voir quand ton OS te balancera un "out of memory" [:icon7]

Reply

Marsh Posté le 06-04-2008 à 22:44:46    

zizouuuu a écrit :

Dans mon demineur lorsque j'essaie de lire un fichier depuis le terminal en tapant ./edit -f nom_fichier.txt
il ne veut pas me lancer mon jeu car j'ai un segmentation fault du un fclose() que j'ai pu voir a l'aide du gdb mais j'ai tout essayé enfin tout ce que je sais mais je n'arrive pas a voir d'ou viens le soucis j'aurais besoin d'un serieu coup de main MERCI a vous voici le code ou cela bug:


Ton code est incomplet et ne peut être testé...


Project   : Forums
Compiler  : GNU GCC Compiler (called directly)
Directory : D:\dev\forums\
--------------------------------------------------------------------------------
Switching to target: default
Compiling: main.c
main.c:1: error: syntax error before "lire"
main.c:1: warning: return type defaults to `int'
main.c: In function `lire':
main.c:4: error: `champs' undeclared (first use in this function)
main.c:4: error: (Each undeclared identifier is reported only once
main.c:4: error: for each function it appears in.)
main.c:4: error: syntax error before "C"
main.c:6: error: `FILE' undeclared (first use in this function)
main.c:6: error: `flot' undeclared (first use in this function)
main.c:8: warning: implicit declaration of function `nb_mine_fichier'
main.c:9: warning: implicit declaration of function `fopen'
main.c:11: error: `NULL' undeclared (first use in this function)
main.c:12: warning: implicit declaration of function `printf'
main.c:15: warning: implicit declaration of function `fscanf'
main.c:16: error: `C' undeclared (first use in this function)
main.c:16: warning: implicit declaration of function `init'
main.c:21: warning: implicit declaration of function `getc'
main.c:23: error: `EOF' undeclared (first use in this function)
main.c:27: error: `PASVU' undeclared (first use in this function)
main.c:31: error: `DEJAVU' undeclared (first use in this function)
main.c:45: warning: implicit declaration of function `fclose'
Process terminated with status 1 (0 minutes, 1 seconds)
12 errors, 8 warnings


---------------
Des infos sur la programmation et le langage C: http://www.bien-programmer.fr Pas de Wi-Fi à la maison : http://www.cpl-france.org/
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed