erreur sur un fprintf

erreur sur un fprintf - C - Programmation

Marsh Posté le 11-10-2005 à 18:49:17    

Bonjour,
Mon program me renvoie une segmentation fault lors de l execution des lignes suivantes:  
 

Code :
  1. ...
  2. /*ouverture du fichier de statistique */
  3. if ((p_stat=fopen("stat.dat","wt" ))==0)
  4.   {
  5.     snprintf(errortext, ET_SIZE, "Error open file %s", "stat.dat" );
  6.     error(errortext, 500);
  7.   }
  8. /*debut de l ecriture */
  9.   fprintf(p_stat," -------------------------------------------------------------- \\n" );
  10. ...


 
L'ouverture de ficher se fait bien. J ai un pointeur p_stat non null et donc je ne rentre pas dans la boucle if, mais par contre lorsque la ligne avec le fprintf est execute ca crash  :(  
J utilise deja les meme lignes de code sous windows et tout marche bien, par contre sous cygwin ca plante... est ce que quelqu'un aurait une idee? J ai essaye de changer le "wt" en "wb" dans le fopen (car le "wt" n'est pas dans mon man de cygwin) mais ca ne change rien.
 
Merci d avance

Reply

Marsh Posté le 11-10-2005 à 18:49:17   

Reply

Marsh Posté le 11-10-2005 à 19:52:53    

soit !, soit == NULL, mais pas 0. que dit perror ?

Reply

Marsh Posté le 11-10-2005 à 20:03:45    

niemad a écrit :

Mon program me renvoie une segmentation fault lors de l execution des lignes suivantes:  

Code :
  1. if ((p_stat=fopen("stat.dat","wt" ))==0)




"wt", ça n'existe pas. C'est "w" pour les fichiers textes.
 
Poste le code complet, mais réduit au minimum qui montre le défaut.


---------------
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

Marsh Posté le 12-10-2005 à 12:36:54    

J etais un peu etonne par le "wt" mais pas sure, bon je l ai change par "w" seulement et voici le code reduit au minimum:
 

Code :
  1. void report()
  2. {
  3.  
  4.   FILE *p_stat;
  5.   /*ici j ai des calculs de statistique et des impressions de resultats a l ecran (stdout)*/
  6. /*ici p_stat == 0x0*/
  7.   if ((p_stat=fopen("stat.dat","w" ))==NULL)
  8.   {
  9.     snprintf(errortext, ET_SIZE, "Error open file %s", "stat.dat" );
  10.     error(errortext, 500);
  11.   }
  12. /*ici p_stat = 0xa12d7ac*/
  13.   fprintf(p_stat," -------------------------------------------------------------\\n" );/*ligne qui renvoie le segfault*/
  14.   fprintf(p_stat,"  This file contains statistics values                                        \\n" );
  15.   fprintf(p_stat," --------------------------------------------------------------\\n" );
  16.   /* d autre fprintf*/
  17. }


 
Effectivement le "==0" et le "wt" n etaient pas top! Merci deja pour ces corrections. Je continue a chercher d ou vient mon erreur, mais toujours pas de solution pour le moment. J ai quand meme l impression que mon fopen renvoie un pointeur p_stat un peu bizarre (les valeurs des champs du pointeur comme flags sont pas a zeros) mais je ne suis pas sure que ce soit anormal. J ai essaye de trouver a quoi un pointer FILE etait cense ressembler sous google, mais j ai pas vraiment trouve ce que je cherchais.

Message cité 1 fois
Message édité par niemad le 12-10-2005 à 12:48:16
Reply

Marsh Posté le 12-10-2005 à 12:38:44    

manque pas un bout ?


---------------
-( BlackGoddess )-
Reply

Marsh Posté le 12-10-2005 à 12:43:43    

blackgoddess a écrit :

manque pas un bout ?


 
Desole c est edite maintenant... petit probleme de frappe la premiere fois  

Reply

Marsh Posté le 12-10-2005 à 13:12:26    

Elle fait quoi ta fonction error() ?
 
errortext, c'est une variable globale ?  [:le poney de mr pink]
 
 
Et "code minimum", c'est "code minimum qui compile et fonctionne pour montrer l'erreur"  :o


Message édité par Elmoricq le 12-10-2005 à 13:12:51
Reply

Marsh Posté le 12-10-2005 à 13:23:06    

Pourquoi tu fais un  snprintf avec une chaîne constante. Tu peux pas faire  directement
error( "Error open file stat.dat", 500);  
?  (c'est quoi ce 500 d'ailleurs ?)
 
Pour ton erreur, je parierais que ce n'est pas la ligne du  fprintf qui est en cause, mais qu'à un moment ou à un autre tu fais une bêtise et tu écris dans la pile ou un truc dans le genre....

Reply

Marsh Posté le 12-10-2005 à 13:31:01    

niemad a écrit :

J etais un peu etonne par le "wt" mais pas sure, bon je l ai change par "w" seulement et voici le code reduit au minimum:


Gaahhh. Il faut faire quoi pour avoir la version qui compile ?


Compiling: main.c
main.c: In function `report':
main.c:4: error: `FILE' 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: `p_stat' undeclared (first use in this function)
main.c:9: warning: implicit declaration of function `fopen'
main.c:9: error: `NULL' undeclared (first use in this function)
main.c:11: warning: implicit declaration of function `snprintf'
main.c:11: error: `errortext' undeclared (first use in this function)
main.c:11: error: `ET_SIZE' undeclared (first use in this function)
main.c:12: warning: implicit declaration of function `error'
main.c:15: warning: implicit declaration of function `fprintf'
main.c:20:7: warning: no newline at end of file


Ce code

Code :
  1. #include <stdio.h>
  2. #define ET_SIZE 128
  3. static void error(char const *s, int err)
  4. {
  5.     fprintf(stderr, "%3d:%s\n", err, s);
  6. }
  7. static void report(void)
  8. {
  9.     FILE *p_stat=fopen("stat.dat","w" );
  10.    
  11.     if (p_stat==NULL)
  12.     {
  13.         char errortext[ET_SIZE];
  14.         snprintf(errortext, ET_SIZE, "Error open file %s", "stat.dat" );
  15.         error(errortext, 500);
  16.     }
  17.     else
  18.     {
  19.         /*ligne qui renvoie le segfault*/
  20.         fprintf(p_stat," -------------------------------------------------------------\n" );
  21.         fprintf(p_stat,"  This file contains statistics values\n" );
  22.         fprintf(p_stat," --------------------------------------------------------------\n" );
  23.        
  24.         /* d autre fprintf*/
  25.         fclose (p_stat);
  26.     }
  27. }
  28. int main (void)
  29. {
  30.     report();
  31.     return 0;
  32. }


produit un fichier stat.dat comme ceci :


 -------------------------------------------------------------
  This file contains statistics values
 --------------------------------------------------------------


Pour moi, pas de problèmes...


Message édité par Emmanuel Delahaye le 12-10-2005 à 13:41:52

---------------
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

Marsh Posté le 12-10-2005 à 13:32:40    

pascal_ a écrit :

Pour ton erreur, je parierais que ce n'est pas la ligne du  fprintf qui est en cause, mais qu'à un moment ou à un autre tu fais une bêtise et tu écris dans la pile ou un truc dans le genre....


 
Moi je parie pour ouverture qui rate et la fonction error() qui permet de continuer sur les fprintf().

Reply

Marsh Posté le 12-10-2005 à 13:32:40   

Reply

Marsh Posté le 12-10-2005 à 13:35:40    

Elmoricq a écrit :

Moi je parie pour ouverture qui rate et la fonction error() qui permet de continuer sur les fprintf().


 

Code :
  1. /*ici p_stat = 0xa12d7ac*/


 
apparement non...

Reply

Marsh Posté le 12-10-2005 à 14:53:31    


Je sais que ca fonctionne si j ecris une fonction basique et donc que mon probleme doit venir d autre part. La ou je ne comprends pas c est que j ai le meme code sous windows et ca marche alors que sous cygwin ca coince.
 
en ce qui concerne le probleme de error qui continue sur fprintf, je ne pense pas que ce soir possible car j' ai fait du pas a pas avec gdb et je ne rentre pas dans le test "if" contenant la fonction error().

Reply

Marsh Posté le 12-10-2005 à 15:02:30    

niemad a écrit :

Je sais que ca fonctionne si j ecris une fonction basique et donc que mon probleme doit venir d autre part. La ou je ne comprends pas c est que j ai le meme code sous windows et ca marche alors que sous cygwin ca coince.
 
en ce qui concerne le probleme de error qui continue sur fprintf, je ne pense pas que ce soir possible car j' ai fait du pas a pas avec gdb et je ne rentre pas dans le test "if" contenant la fonction error().


Il y a autre chose ailleurs. Il faut réduire le code jusqu'à ce que l'erreur disparaisse. Evidemment, c'est beaucoup plus facile quand le code est 'modulaire'... Il est alors facile d'en déduire le code fautif.
 
Je sens bien un débordement de chaine...
 


---------------
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

Marsh Posté le 12-10-2005 à 15:04:24    

j'exige la backtrace :o

Reply

Marsh Posté le 12-10-2005 à 17:42:26    

Desole de ne pas fournir un code executable qui reproduit l erreur, mais je n arrive pas a produire un code minimum qui reproduit l erreur assez petit pour etre mis ici! J'ai par contre trouve une ligne qui, lorsqu elle est enleve resouds mon segfault. J'ai:
 

Code :
  1. #include <stdio.h>
  2. int *var1;
  3. int *var2;
  4. void free_var()
  5. {
  6.    free(var1);/*si j enleve cette ligne le fprintf de report marche bien*/
  7.    free(var2);
  8. }
  9. int main (void)
  10. {
  11.    ...
  12.     free_var();/*fonction utiliser pour liberer la memoire*/
  13.     report();
  14.     return 0;
  15. }


 
Je ne comprends pas comment mon free peut influencer mon pointeur de fichier dans report!
 
Pour repondre a Taz: j aimerais bien fournir un backtrace, mais je suis sous cygwin et je n obtient qu un stack dump et gdb n arrive pas a l ouvrir. Je ne sais pas comment obtenir un core dump sous cygwin...

Reply

Marsh Posté le 12-10-2005 à 17:45:35    

Outch. Comportement aléatoire sur un truc qui n'a rien à voir == gestion de la mémoire foireuse quelque part.
 
Si en plus ça "se résoud" (aléatoirement, donc) en retirant un free(), tu n'as plus qu'à inspecter tous tes malloc(), utilisation des blocs alloués, et free() qui vont avec.
 
Amuse-toi bien si le programme est un peu alambiqué, c'est l'une des pire erreur possible (quoique avec un truc genre Purify ça se trouve vite [:petrus75] )


Message édité par Elmoricq le 12-10-2005 à 17:45:53
Reply

Marsh Posté le 12-10-2005 à 18:00:29    

... Merci pour le message d encouragement ;) ... et oui le porgramme est "un peu" alambique! En plus la pluspart du code n a pas ete ecrit par moi meme :( Je vais aller faire un tour du cote de Purify.

Reply

Marsh Posté le 12-10-2005 à 18:13:55    

gcc -g machin.c -o machin.exe
gdb ./machin.exe
> bt full

Reply

Marsh Posté le 12-10-2005 à 18:41:26    

Taz a écrit :

gcc -g machin.c -o machin.exe
gdb ./machin.exe
> bt full


 
Lorsque je fais ca gdb repond "No Stack" si le programme n est pas en train de tourner (i.e. je n ai pas attache le processus correspondant) ou me renvoie seulement quelques lignes d information sur mon main() si le processus a ete attache.

Reply

Marsh Posté le 12-10-2005 à 18:49:51    

niemad a écrit :


Code :
  1. int *var1;
  2. int *var2;




Des globales ? Question modularité, t'es mal barré...

Citation :

Je ne comprends pas comment mon free peut influencer mon pointeur de fichier dans report!


C'est un bête comportement indéfini. Par exemple, libération d'un bloc déjà libéré, ou d'une adresse invalide (la valeur du pointeur a changé, var1++ etc.)
 


---------------
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

Marsh Posté le 12-10-2005 à 19:17:48    

oops
 
> run
> bt full

Reply

Marsh Posté le 14-10-2005 à 22:38:43    

Hors sujet : moi j'aime bien les globales. Faut arreter de crasher systematiquement sur les globales. Si un projet et bien modularise, je ne vois aucun probleme a avoir des globales "static" (les vraies globales pas static, c'est autre chose). Ca peut rendre le code plus simple et plus performant. Comme les goto. Ceux qui ne veulent pas de globales static, c'est ceux qui ont des fichiers de 10000 lignes. Ceux qui crachent sur les goto, c'est ceux qui ont des fonctions de 1000 lignes. Le probleme est ailleurs.

Reply

Marsh Posté le 14-10-2005 à 23:36:51    

Ah mais les globales, c'est utile. Mais dans des cas précis, et ça s'utilise avec parcimonie.  
 
Par contre les pointeurs en variables globales, là, ça me fait peur en général.
Bon, faut dire que j'ai été traumatisé par un logiciel qui tournait dans une banque (j'vous raconte pas le prix de la license), y avait quelques Mo de fichiers sources, et quasi tout était en variablse globales, modifiées n'importe où mais pas n'importe comment. La moindre modif entrainait des effets de bords monstrueux.  
Je me voyais bon pour la camisole. :sweat:


Message édité par Elmoricq le 14-10-2005 à 23:37:18
Reply

Marsh Posté le 15-10-2005 à 09:42:05    

matafan a écrit :

Hors sujet : moi j'aime bien les globales. Faut arreter de crasher systematiquement sur les globales. Si un projet et bien modularise, je ne vois aucun probleme a avoir des globales "static" (les vraies globales pas static, c'est autre chose). Ca peut rendre le code plus simple et plus performant. Comme les goto. Ceux qui ne veulent pas de globales static, c'est ceux qui ont des fichiers de 10000 lignes. Ceux qui crachent sur les goto, c'est ceux qui ont des fonctions de 1000 lignes. Le probleme est ailleurs.


Le problème est que ça rend le code non instanciable et non réentrant... Au niveau applicatif, ca peut être acceptable, mais dans une optique de réutilisation où quasiment 'tout est bibliothèque' (pour paraphraser le fameux 'Under Unix, all is file'), ça ne marche plus. Une fois que du code est écrit avec des globales, pour le rendre éligible à la mise en bibliothèque, il faut y repasser du temps, de la validation etc. Pour moi, c'est simple, tout est bibliothèque et donc instanciable. Pas de globales.
 
Reste le problème des performances. Si effectivement, après profiling sérieux et optimisation des algorithmes, il reste un goulot d'étranglement du à une ou deux indirections de plus, pourquoi pas une solution 'jetable' avec une globale, mais il fa valloir argumenter sérieusement pour en arriver là!
 


---------------
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

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

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