un segementation fault a cause d'un fclose??? - C - Programmation
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().
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
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().
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() ?
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().
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
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
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.
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 :
|
L'algo bouclera une fois de trop
xilebo a écrit : |
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 :
|
Le C permet d'écrire
Code :
|
Ce qui se traduit par
Code :
|
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...
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.
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 ?? ()
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 ?
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.
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
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...
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" )); |
n'hésite pas à revenir nous voir quand ton OS te balancera un "out of memory"
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 |
Ton code est incomplet et ne peut être testé...
|
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