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 : mémoire tampon?


Sujet :

C

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 18
    Par défaut Erreur de segmentation : mémoire tampon?
    Bonjour,

    Lorsque je lance mon programme (cf. ci-dessous), il plante dès le début et un terrible erreur de segmentation s'affiche sur mon terminal. Le hic c'est que mon programme fonctionnait bien... avec des fichiers de taille moins importante. Je me suis un peu renseigné sur les fonctions que j'utilise (je débute), et je pense que la mémoire tampon en serait la cause.

    Je lis chaque ligne de mon fichier "extract", et dès que le champ R que je calcule à partir de ce que je lis est différent de 0, je lis le fichier "TRACKBODYX" (X correspondant au numéro situé dans la ligne lue), jusqu'à ce que le champs time corresponde au champs temps (je souhaite récupérer les données du "TRACKBODY" sur l'instant juste avant celui de la ligne du "extract").

    Le problème serait donc la taille trop importante des mes fichiers "TRACKBODY", qui est de 350Mo - ça en fait des lignes. Puisqu'avant ça marchait... Connaissez vous un moyen d'éviter l'erreur?

    Je vous laisse en juger: (merci d'avance)

    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
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <math.h>
     
     
    int main(void)
    {
      FILE *traitement=fopen("extract","r");
      FILE *calcul=fopen("matlab","w");
     
      int candidat,antagoniste,pas;
      float temps,Rloc_s,Rloc_t,Rloc_n,Vloc_s,Vloc_t,Vloc_n,gap,s1,s2,s3,t1,t2,t3,n1,n2,n3,q1,q2,q3;
      int cpt=0;                                                          /*   données  */
      float Vt,Vn,Vimp,Rx,Ry,Rz,Rt,Rn,R,alpha,Et,En,Etot;      /*  calculées */ 
      char fname[100];
     
      while(!feof(traitement))
        {  
          fscanf(traitement,"%d %f %d %d %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f %f",&pas,&temps,&candidat,&antagoniste,&Rloc_s,&Rloc_t,&Rloc_n,&Vloc_s,&Vloc_t,&Vloc_n,&gap,&s1,&s2,&s3,&t1,&t2,&t3,&n1,&n2,&n3,&q1,&q2,&q3);
          Rx = Rloc_s*s1+Rloc_t*t1+Rloc_n*n1;
          Ry = Rloc_s*s2+Rloc_t*t2+Rloc_n*n2;
          Rz = Rloc_s*s3+Rloc_t*t3+Rloc_n*n3;
          Rt = sqrt(Rx*Rx+Ry*Ry);
          Rn = Rz;
          R = sqrt(Rx*Rx+Ry*Ry+Rz*Rz);
     
          if(R!=0)
    	{
    	  cpt++;
    	  sprintf(fname,"TRACKBODY%d",candidat);
    	  FILE* body_lu=fopen(fname,"r");
    	  float time,x,y,z,vx,vy,vz,ox,oy,oz;
    	  float time_last,x_last,y_last,z_last,Vx_last,Vy_last,Vz_last,Ox_last,Oy_last,Oz_last;
    	  while((fgetc(body_lu))!=EOF)
    	    {
    	      fscanf(body_lu,"%f %f %f %f %f %f %f %f %f %f",&time,&x,&y,&z,&vx,&vy,&vz,&ox,&oy,&oz);
    	      if(time==temps)
    		{
    		  Vt = sqrt(Vx_last*Vx_last+Vy_last*Vy_last);
    		  Vn = Vz_last;
    		  Vimp = sqrt(Vn*Vn+Vt*Vt);
    		  alpha = (180*113/355)*asin(Vt/Vimp);
    		  Et = Rt*Vt;
    		  En = Rn*Vn;
    		  Etot = 0.5*7000*4*(113/355)*(2*2*2)*(6.283185308*6.283185308)/3;
    		  fprintf(calcul,"%d %.7f %d %.7f %.7f %.7f %.7f %.7f %.7f %.7f %.7f %.7f %.7f %.7f %.7f %.7f %.7f\n",cpt,temps,candidat,q1,q2,q3,Vt,Vn,Vimp,alpha,Rt,Rn,R,Et,En,Etot,En/Etot);
    		}
    	      time_last=time;
    	      x_last=x;
    	      y_last=y;
    	      z_last=z;
    	      Vx_last=vx;
    	      Vy_last=vy;
    	      Vz_last=vz;
    	      Ox_last=ox;
    	      Oy_last=oy;
    	      Oz_last=oz;
    	    }
    	  fclose(body_lu);
    	} 
        }
     
      fclose(traitement);
      fclose(calcul);
     
      return 0;
    }

    Extraits de mes fichiers :

    extract:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    2696 0.0033700 152 156 37.8328590 -144.0532074 2485.6660156 0.2344440 -0.8926741 6.2743020 0.000003298907 -0.0000000 -1.0000000 -0.0000000 -1.0000000 0.0000000 0.0000000 0.0000000 0.0000000 -1.0000000 -0.0033009 0.0081162 0.0300000
    2709 0.0033862 153 156 -6.8193688 -208.8645935 2444.7829590 -0.0423000 -1.2955710 6.1711059 0.000004544012 -0.0000000 -1.0000000 -0.0000000 -1.0000000 0.0000000 0.0000000 0.0000000 0.0000000 -1.0000000 -0.0052620 0.0123830 0.0300000
    2865 0.0035813 149 156 -2.9766669 -137.7306061 2384.4919434 -0.0184479 -0.8535847 6.0189199 0.000003128631 -0.0000000 -1.0000000 -0.0000000 -1.0000000 0.0000000 0.0000000 0.0000000 0.0000000 -1.0000000 -0.0039167 -0.0039475 0.0300000
    2875 0.0035938 148 156 -5.5943542 -134.4871979 2344.7399902 -0.0347288 -0.8348730 5.9185791 0.000005333647 -0.0000000 -1.0000000 -0.0000000 -1.0000000 0.0000000 0.0000000 0.0000000 0.0000000 -1.0000000 -0.0039583 -0.0081305 0.0300000

    TRACKBODY1 :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    0.1250000e-05 -0.2274874e-01 -0.2274874e-01  0.2003879e-02  0.0000000e+00  0.0000000e+00  0.6205829e+01  0.0000000e+00  0.0000000e+00  0.0000000e+00
      0.2500000e-05 -0.2274874e-01 -0.2274874e-01  0.2011636e-02  0.0000000e+00  0.0000000e+00  0.6205817e+01  0.0000000e+00  0.0000000e+00  0.0000000e+00
      0.3750000e-05 -0.2274874e-01 -0.2274874e-01  0.2019393e-02  0.0000000e+00  0.0000000e+00  0.6205804e+01  0.0000000e+00  0.0000000e+00  0.0000000e+00
      0.5000000e-05 -0.2274874e-01 -0.2274874e-01  0.2027150e-02  0.0000000e+00  0.0000000e+00  0.6205792e+01  0.0000000e+00  0.0000000e+00  0.0000000e+00
      0.6250000e-05 -0.2274874e-01 -0.2274874e-01  0.2034908e-02  0.0000000e+00  0.0000000e+00  0.6205780e+01  0.0000000e+00  0.0000000e+00  0.0000000e+00
      0.7500000e-05 -0.2274874e-01 -0.2274874e-01  0.2042665e-02  0.0000000e+00  0.0000000e+00  0.6205768e+01  0.0000000e+00  0.0000000e+00  0.0000000e+00
      0.8750000e-05 -0.2274874e-01 -0.2274874e-01  0.2050422e-02  0.0000000e+00  0.0000000e+00  0.6205755e+01  0.0000000e+00  0.0000000e+00  0.0000000e+00

  2. #2
    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
    Il faudrait d'abord sécuriser le programme :
    - lors d'une tentative d'ouverture d'un fichier, s'assurer de la réussite (surtout pour body_lu) en vérifiant que la valeur de retour de fopen() est différente de NULL.
    - vérifier la valeur de retour de fscanf() plutôt qu'utiliser feof() (voir plus bas)
    - cette écriture est étrange
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    while((fgetc(body_lu))!=EOF)
    {
       fscanf(body_lu,"%f %f %f %f %f %f %f %f %f %f",&time,&x,&y,&z,&vx,&vy,&vz,&ox,&oy,&oz);
    ...
    }
    On attend plutôt
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    while(fscanf(body_lu,"%f %f %f %f %f %f %f %f %f %f",&time,&x,&y,&z,&vx,&vy,&vz,&ox,&oy,&oz)== 10))
    {
    ...
    }
    Sur le reste du code
    *
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    float time_last,x_last,y_last,z_last,Vx_last,Vy_last,Vz_last,Ox_last,Oy_last,Oz_last;
    while((fgetc(body_lu))!=EOF)
    {
      fscanf(body_lu,"%f %f %f %f %f %f %f %f %f %f",&time,&x,&y,&z,&vx,&vy,&vz,&ox,&oy,&oz);
      if(time==temps)
      {
        Vt = sqrt(Vx_last*Vx_last+Vy_last*Vy_last);
    ...
    Vx_last et Vy_last ne sont pas (forcément) initialisés

    * Sauf erreur, un grand nombre de variables ne sont pas utilisées

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 18
    Par défaut
    Merci diogene pour la réponse. J'ai suivi vos conseils.
    Concernant la condition de lecture, vous avez raison : le fscanf dans le while est plus approprié.
    Il est vrai aussi que pas mal de variables(les *_last) n'étaient pas utilisées.
    Par contre pour la vérification que l'ouverture des fichiers s'est bien passée, je ne comprend pas pourquoi en mettre une. Mes fichiers existent bien. La fonction fopen peut "déconner"?

  4. #4
    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
    La fonction fopen peut "déconner"?
    Mais il peut y avoir des situations où l'ouverture peut échouer et il faut les détecter, sinon le programme va planter sans raisons apparentes. Ce peut être un fichier qui n'existe pas, ou n'est pas dans le bon répertoire, une erreur sur son nom, ou on n'a pas les droits d'accès ou on a trop de fichiers ouverts ou...
    Le test est simple et permet de s'assurer que si il y a problème, au moins ce n'est pas de ce coté là. On peut le considérer comme indispensable.
    Dans ton cas, puisque l'erreur de segmentation ne semble pas venir du code à première vue, il faut éliminer les sources potentielles d'erreurs.

  5. #5
    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
    Citation Envoyé par sayanmehdi Voir le message
    Par contre pour la vérification que l'ouverture des fichiers s'est bien passée, je ne comprend pas pourquoi en mettre une. Mes fichiers existent bien. La fonction fopen peut "déconner"?
    En programmation, il faut faire en sorte de limiter les problèmes au maximum, les bugs ou autres plantages ; il faut partir du principe qu'un problème peut toujours arriver même dans des circonstances où on est convaincu du contraire. Par exemple, même si tu sais que ton fichier existe, il peut toujours y avoir un problème d'ouverture, soit parce que le fichier est déjà ouvert (je ne sais pas si dans ce cas l'ouverture est assurée ou si cela dépend de l'OS ? à voir), soit parce que le fichier a été supprimé/déplacé entre-temps sans que tu le saches, soit parce qu'il y a un problème de disque (secteur défectueux juste à cet endroit-là ou autre), etc...
    Il est plus que conseillé de toujours tester la valeur retour des fonctions pour éviter les mauvaises surprises.

  6. #6
    Membre averti
    Profil pro
    Inscrit en
    Avril 2010
    Messages
    18
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2010
    Messages : 18
    Par défaut
    OK, j'ai compris - je m'empresse de rajouter un test sur l'ouverture, merci à tous les deux du conseil.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Erreur de segmentation
    Par Trunks dans le forum C
    Réponses: 3
    Dernier message: 06/10/2005, 18h28
  2. Qu'est-ce que "le dépassement de mémoire tampon"
    Par allex2108 dans le forum Autres Logiciels
    Réponses: 1
    Dernier message: 13/09/2005, 14h33
  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