Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
657 connectés 

  FORUM HardWare.fr
  Programmation
  C

  [ C ] Erreur de segmentation (core dumped)

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

[ C ] Erreur de segmentation (core dumped)

n°1810101
AigleRoyal
Posté le 09-11-2008 à 13:16:33  profilanswer
 

Bonjour à tous,
 
Je suis débutant en C et je me mêle les pinceaux avec les pointeurs en ce moment. Je vous expose mon problème.
Je souhaite :
 
1 - Aller chercher dans un fichier une ligne qui contient par exemple : "etat1 etat2 etat3 e4 e5#" (espaces compris)
 
2 - Maintenant, je voudrais créer un tableau de 5 pointeurs. Chaque pointeur, pointera sur chacune des chaines de caractères. Autrement dit, si on appelle, le tableau : tab_pointeurs, on aura :
 
tab_pointeurs[0] qui pointe sur "etat1"
tab_pointeurs[1] qui pointe sur "etat2"
......
tab_pointeurs[4] qui pointe sur "e5"
 
SEULEMENT, on ne sait pas à l'avance combien d'états on aura dans le fichier, et donc de combien de pointeurs on aura besoin. Et on ne sait pas non plus quelle taille feront chaque chaine de caractères. D'où les allocations mémoires.
 
Je ne sais pas si le problème est assez clair :).
 

Code :
  1. typedef char* t_etats;
  2. 'etats' est une variable globale. Un tableau de 500 caractères maxi qui contiendra toute la ligne du fichier (espaces compris).
  3. i est la variable qui permet de se déplacer dans ce tableau.
  4. //////////////////////////////////////// FONCTION RECHERCHER_ETATS ///////////////////////////////////////////////
  5. /*   
  6. * Recherche les états de la machine dans le fichier 'machine'.
  7. * Préconditions : Le fichier existe
  8. * Postconditions : Renvoie un tableau de chaîne de caractères (les états).
  9. */
  10. //////////////////////////////////////////////////////////////////////////////////////////////////////////////////
  11. t_etats* rechercher_etats(FILE* fichier){
  12.     char marqueur = '$'; t_etats* etats_ret=NULL;
  13.    
  14.     /* Parcours du fichier ligne par ligne. On sort de la boucle une fois le mot trouvé.*/
  15.     while (!feof(fichier)){
  16.          
  17.           fgets(etats,sizeof(etats),fichier);         
  18.           if(etats[0] != marqueur){
  19.                 break
  20.           } 
  21.     }
  22.     printf("Etats recherches : %s",etats);
  23.     printf("Taille : %d\n",strlen(etats)-2); // on enlève le '#' et le marqueur de fin '\0'
  24.     int unsigned i=0; int j=0; int unsigned k=0; int maxetats=0; int taille_nom_etat=0; int t=0;
  25.            
  26.     // On compte le nombre total d'états présents pour la machine. En comptant le nombre d'espace entre leurs noms et en ajoutant 1.
  27.     while(k<strlen(etats)-2){
  28.        if(etats[k]==' '){ 
  29.           maxetats++; 
  30.        }
  31.        k++;
  32.     }
  33.     maxetats++;
  34.     printf("nbre d'etats : %d\n",maxetats);
  35.     /* tab_etat est un tableau de pointeurs. Sa taille (maxetats) n'est pas connue à l'avance. Mais, on en aura besoin un peu plus haut dans la fonction  
  36.      * "indice_etat". Sa taille réelle est contenue dans la variable maxetats et on ajoute une case de plus qui contiendra toujours NULL. Cette case jouera le rôle  
  37.      * de marqueur de fin et nous permettra à l'aide d'une boucle de déterminer la taille du tableau. Les indices vont de 0 à maxetats-1. Donc, si on ajoute une  
  38.      * colonne de plus, elle aura pour indice 'maxetats'.
  39.      */
  40.     t_etats tab_etat[maxetats+1]; tab_etat[maxetats]=NULL;
  41.     for(j=0;j<maxetats;j++){
  42.  
  43.   /* On compte la taille en caracteres de chaque etat.
  44.    * strlen(mot)-2 pour éviter de prendre le dernier caractère de la chaine # et le marqueur de fin : '\0'.
  45.    */
  46.                    
  47.    while(etats[i]!=' ' && i<strlen(etats)-2){
  48.        i++;             
  49.                taille_nom_etat++;                                                                   
  50.     }
  51.     printf("taille du nom de l'etat = %d\n",taille_nom_etat);
  52.     /*
  53.      * Pour chaque état, on alloue une zone mémoire de taille variable qui contiendra son nom (chaine de caractère qui le représente). Ceci, en partant du  
  54.              * principe que les noms (des états) i.e les chaines de caractère sont de tailles différentes.
  55.      *
  56.      * Si  par exemple, nous avons les états : 'etat1' 'etat2', 'e3', 'q4', 'eta5'
  57.      * On allouera :
  58.      * Une zone mémoire de 5 caractères pour chacun des états 1 et 2.  
  59.      * Une zone de 2 caractères pour chacun des états 3 et 4 et
  60.              * Une zone de 4 caractères pour l'état 5.
  61.      * tab_etat est un tableau de pointeurs sur ces caractères. Donc,
  62.      * tab_etat[0] pointera sur l'état 1 et donc sur la chaîne : 'etat1'
  63.      * tab_etat[1] pointera sur l'état 2 et donc sur la chaîne : 'etat2'
  64.      * tab_etat[2] pointera sur l'état 3 et donc sur la chaîne : 'e2'
  65.      * tab_etat[3] pointera sur l'état 4 et donc sur la chaîne : 'q4'
  66.      * tab_etat[4] pointera sur l'état 5 et donc sur la chaîne : 'eta5'
  67.      */
  68.      tab_etat[j] = malloc(sizeof(char)*taille_nom_etat);
  69.      if(tab_etat[j]==NULL){
  70.          printf("\n Allocation Impossible \n" );
  71.          exit(EXIT_FAILURE);
  72.      }
  73.      int temp; temp = taille_nom_etat; int taille; taille = strlen(etats)-2;
  74.      if(i <= taille){
  75.           for(t=0;t<taille_nom_etat;t++){
  76.                tab_etat[j][t]=etats[i-temp];
  77.                temp--;
  78.           }
  79.       }
  80.       i++;
  81.       taille_nom_etat=0;             
  82.      }             
  83.                          
  84.      printf("Les etats sont : \n" );
  85.      for(j=0;j<maxetats;j++){
  86.           printf("%s\n",tab_etat[j]); 
  87.      }
  88.      printf("\n" );
  89.      etats_ret = tab_etat;
  90.      return etats_ret;
  91. }
  92. // Fin de la fonction rechercher_etats


 
Merci d'avance


Message édité par AigleRoyal le 10-11-2008 à 13:07:12
mood
Publicité
Posté le 09-11-2008 à 13:16:33  profilanswer
 

n°1810102
o'gure
Multi grognon de B_L
Posté le 09-11-2008 à 14:25:02  profilanswer
 

Ce sujet a été déplacé de la catégorie OS Alternatifs vers la categorie Programmation par O'gure


---------------
Relax. Take a deep breath !
n°1810104
Joel F
Real men use unique_ptr
Posté le 09-11-2008 à 14:47:38  profilanswer
 

Ton code est fouilli. Decoupes ca en fonction a but restreint (lire le fichier, creer les tableaux, les remplir) tu y verras deja plus clair.

n°1810120
Taz
bisounours-codeur
Posté le 09-11-2008 à 15:20:27  profilanswer
 

n'utilise pas feof (ou alors lis sa documentation).
 
while(fgets(...) != NULL) est la bonne méthode.

n°1810282
olivthill
Posté le 10-11-2008 à 09:38:09  profilanswer
 

Ici, dans ce programme, c'est un peu fouillis, surtout parce que l'indentation est mauvaise, mais sinon la longueur n'est pas exagérée, il y a des commentaires, et l'absence de sous-fonctions n'est pas la cause du problème. Ici, dans ce programme, feof() n'est pas non plus la cause du problème.
 
Le cause est la mauvaise utilisation de la variable "i".
 

n°1810290
el muchach​o
Comfortably Numb
Posté le 10-11-2008 à 10:04:24  profilanswer
 

Si tu cherchais au moins où ça plante... la valeur de i, etc. C'est le B.A.BA du débogage.


---------------
Les aéroports où il fait bon attendre, voila un topic qu'il est bien
n°1810385
AigleRoyal
Posté le 10-11-2008 à 13:33:59  profilanswer
 

Bonjour,
 
J'ai essayé de débugger avec gdb et je n'ai rien vu. La valeur de i ne pose pas de problèmes. Pour tester, j'ai rajouté 2 instructions au sortir de la fonction. Je rappelle qu'elle renvoit un tableau de pointeurs.
 
     tableau_etats = rechercher_etats(p_fichierM);     // où p_fichierM est un pointeur sur un fichier contenant la ligne "e1 e2 e3 e4 e5#"
 
     printf("Avant : tableau_etats[0] = %s\n",tableau_etats[0]);
     printf("Tout est OK\n" );
     printf("Apres : tableau_etats[0] = %s\n",tableau_etats[0]);
 
     Il affiche :
 
    "Avant : tableau_etats[0] = e1
     Tout est Ok
     Erreur de segmentation (core dumped)" Au lieu d'afficher "Après : tableau_etats[0] = e1"
 
Autrement dit, j'ai l'impression qu'entre deux instructions, la valeur du pointeur est supprimée ?!!! Deux instructions identiques séparées par l'affichage de "Tout est Ok" et l'une donne la bonne valeur et après, PLUS RIEN. Une erreur de segmentation.
 
J'essaie de débogger avec valgrind s'il en y a qui connaissent et je vous tiens au courant.
 
A tout à l'heure
 
AR


Message édité par AigleRoyal le 10-11-2008 à 13:35:27
n°1810414
philippe06
Posté le 10-11-2008 à 14:11:51  profilanswer
 

1. typedef char* t_etats;
 
45. t_etats tab_etat[maxetats+1]; tab_etat[maxetats]=NULL;
 
en fait l'erreur c'est ligne 45. Je suis surpris que ca compile en fait. Faut faire un malloc à la place d'une déclaration.


---------------
Aimer les femmes intelligentes est un plaisir de pédéraste. (Charles Baudelaire) - Vous vulgarisez :o (Jean-Kevin Dubois)
n°1810431
AigleRoyal
Posté le 10-11-2008 à 14:49:24  profilanswer
 

Ok, merci Philippe. Je fais ça et je te met au parfum :)
 
Mais, quelle est réellement la différence entre un malloc d'une taille fixe et la déclaration d'un tableau de la même taille fixe ? Y a-t-il une différence en mémoire ?
 
AR

n°1810433
AigleRoyal
Posté le 10-11-2008 à 14:58:25  profilanswer
 

Putain, ça marche NIIIIIIIIIIIIKKKKKKKKKKELL. Ca fait des jours que je cherche... Avec différents déboggeurs.
 
Tu m'expliques Philipe stp ?
 
Je crois qu'une fois que j'aurais compris ça, ça restera gravé à TOUT JAMAIS. Bon, alors pourquoi faire un malloc plutôt que de déclarer un tableau ?
Je suis prêt à apprendre ma leçon...
 
AR

mood
Publicité
Posté le 10-11-2008 à 14:58:25  profilanswer
 

n°1810438
philippe06
Posté le 10-11-2008 à 15:10:41  profilanswer
 

Oui, il y a une différence en mémoire, c'est tout à fait ça:
malloc -> tas
déclaration -> pile ou "zone statique"
 
pour une déclaration, il faut connaitre la taille avant l'execution. Si tu veux faire une zone mémoire de taille variable, il faut faire des mallocs.


---------------
Aimer les femmes intelligentes est un plaisir de pédéraste. (Charles Baudelaire) - Vous vulgarisez :o (Jean-Kevin Dubois)
n°1810955
morph
Posté le 11-11-2008 à 21:45:49  profilanswer
 

int foo(int n)
{
   char tab[n];
   ...
}
 
 c'est tout à fait possible en C99

n°1810966
philippe06
Posté le 11-11-2008 à 22:06:30  profilanswer
 

Je m'en souviendrais ...


---------------
Aimer les femmes intelligentes est un plaisir de pédéraste. (Charles Baudelaire) - Vous vulgarisez :o (Jean-Kevin Dubois)
n°1810967
Elmoricq
Modérateur
Posté le 11-11-2008 à 22:08:32  profilanswer
 

morph a écrit :

int foo(int n)
{
   char tab[n];
   ...
}
 
 c'est tout à fait possible en C99


 
Possible, mais je ne sais pas ce qui leur est passé par la tête pour nous pondre les VLA. Probablement une grosse pierre.
 
Mise en situation :
- n est négatif > plantage
- n est abusivement grand > plantage
- problème d'allocation > impossible de le savoir
 
Bref, les VLA, c'est pas une bonne idée je trouve. :/

n°1810985
Joel F
Real men use unique_ptr
Posté le 11-11-2008 à 23:02:00  profilanswer
 

Sachant que 'abusivement grand' ca commence à 1024 double :E

n°1810987
Amonchakai
Posté le 11-11-2008 à 23:15:17  profilanswer
 

Juste pour ma culture VLA, c'est l'acronyme de quoi ? (le 'L' et 'A', j'imagine que c'est Local Allocation)

n°1810988
Elmoricq
Modérateur
Posté le 11-11-2008 à 23:33:23  profilanswer
 

Variable-Length Array.

n°1810994
Amonchakai
Posté le 12-11-2008 à 07:45:16  profilanswer
 

ok, merci


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  [ C ] Erreur de segmentation (core dumped)

 

Sujets relatifs
Programmation Threads en C++utiliser une dll compilée en C# dans un projet VisualC++
Exercices programmation C++pb erreur dans mon code
Erreur d’exécution 7, mémoire insuffisanteVBA - C++ - DLL
Récupération de temps de réponse (PING) en C[DRUPAL] C'est içi?
probleme de programmation en Cerreur " objet requis "
Plus de sujets relatifs à : [ C ] Erreur de segmentation (core dumped)


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR