Erreur de segmentation en C

Fermé
sabine - 23 déc. 2009 à 17:09
{psycho.} Messages postés 101 Date d'inscription mardi 22 décembre 2009 Statut Membre Dernière intervention 4 septembre 2010 - 23 déc. 2009 à 19:27
Bonjour,
voici le programme suivant qui choisit un mot parmi une liste, et qui met dans un tableau les caractères '_' tant que le mot contient une lettre:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void mettre(char *mot, char tab[]){
int i=0;
while((*mot+i-1) != '\0'){
tab[i]='_';
i++;
}
if((*mot+i-1)=='\0'){
tab[i]='\0';
}
}


int main(){
int i;
char words[3][15]={"baleine","tortue","meduse"};
char *mot;
srand(time(NULL));
mot=words[rand()%3];
char tableau[20];
mettre(mot, tableau);
return 0;
}

tant que mot n'est pas vide, on met _ dans tableau, mais j'ai une erreur de segmentation , pourtant la variable mot est bien initialisé dans le main, quelqu'un voit il d'où vient l'erreur svp?

merci

8 réponses

{psycho.} Messages postés 101 Date d'inscription mardi 22 décembre 2009 Statut Membre Dernière intervention 4 septembre 2010 8
23 déc. 2009 à 17:18
Salut,
Pourquoi ce "-1" dans ton while :
while((*mot+i-1) != '\0')

En faisant ainsi, lorsque i est égal à 0, tu essayes d'accéder au dernier octet de mémoire avant la première lettre de ton mot. Donc si ton programme n'a pas les droits dessus, ça plante.
0
oui psycho tu as raison et j'avais initialisé i=1 avnt meme ta réponse mais j'ai tjs une erreur de segmentation...
0
{psycho.} Messages postés 101 Date d'inscription mardi 22 décembre 2009 Statut Membre Dernière intervention 4 septembre 2010 8
23 déc. 2009 à 17:27
Arf, non, n'initialise pas à 1, laisse ton init à 0, mais enlève ton -1 du while, c'est beaucoup plus logique et c'est une bonne habitude à prendre étant donné qu'en C l'indexation des tableaux commence systématiquement à 0.

Pour ton segfault, si ça ne vient pas de là, je regarderai ça dans la soirée, là je dois y aller!
0
{psycho.} Messages postés 101 Date d'inscription mardi 22 décembre 2009 Statut Membre Dernière intervention 4 septembre 2010 8
23 déc. 2009 à 17:31
Arf, CCM m'a fait sauter mon message, je la refais.

Pour l'initialisation, tu devrais plutôt la laisser à 0 et enlever ton -1, c'est plus logique et c'est surtout une bonne habitude à prendre étant donné que l'indexation des tableaux en C commence systématiquement à 0 (comme dans la plupart (tous?) des autres langages.)

Pour ton segfault, si ça ne vient pas de là, je me pencherai dessus dans la soirée, là je dois y aller donc pas le temps tout de suite.
0
merci psycho c'est gentil, je vais essayer de trouver la solution en attendant mais sans grand espoir
0
voici un corrigé de ton programme:


#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void mettre(char *mot, char tab[]){
  int i=0;
  while( *(mot + i ) != '\0'){ // et non *mot + i 
    tab[i]='_';
    i++;
  }
  if( *(mot+i )=='\0'){ // idem
    tab[i]='\0';
  }
}


int main(){
  //int i;
  char words[3][15]={"baleine","tortue","meduse"};
  char *mot;
  srand(time(NULL));
  mot=words[rand()%3];
  char tableau[20]; // pourkoi un tableau de 20 elements, vu kil doit autant de _ que de caractere dans mot
                           // il serait preferable que tu cree un tableau de taille = strlen(mot) ?
  mettre(mot, tableau);
  return 0;
} 
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
Salut,

A vrai dire je n'ai pas trop compris ce que tu veux.

lami20j@debian:~$ cat sabine.c
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include<string.h>

int mettre(char *mot, char tab[]){
  int i=0;
  while((*mot++) != '\0')
    tab[i++]='_';
  tab[i]='\0';
  return i;
}


int main(){
  int taille,i;
  char *mot;
  char tableau[20];
  char words[3][15]={"baleine","tortue","meduse"};
  mot=malloc(15*sizeof(char));

  srand(time(NULL));
  strcpy(mot,words[rand()%3]);
  printf("%s\n",mot);
  taille=mettre(mot, tableau);

  printf("%d : ",taille);
  for(i=0;i<taille;++i)
    printf("%c ",tableau[0]);
  printf("\n");
  free (mot);
  return 0;
}
lami20j@debian:~$ gcc -Wall sabine.c
lami20j@debian:~$ ./a.out
baleine
7 : _ _ _ _ _ _ _
lami20j@debian:~$ ./a.out
tortue
6 : _ _ _ _ _ _
lami20j@debian:~$ ./a.out
tortue
6 : _ _ _ _ _ _
lami20j@debian:~$ ./a.out
tortue
6 : _ _ _ _ _ _
lami20j@debian:~$ ./a.out
meduse
6 : _ _ _ _ _ _
0
salut lamij, oui en fait je m'étais rendue compte de mon erreur en remplçant ma faute de frappe que tu signales bien par mot[i], donc j'ai bien ma fonction suivante:

void mettre(char *mot, char tab[]){
int i=0;
while(*(mot+i) != '\0'){
tableau[i]='_';
i++;
}
tab[i]='\0';
}

cette fonction m'a l'air valide mais quand je la teste en main j'ai une boucle infinie curieusement:


int main(){
int i=0;
char words[3][20]={"baleine","tortue","meduse"};
char *mot;
srand(time(NULL));
mot=words[rand()%3];
char tab[20];
mettre(mot, tab);
printf("Mot:");
while(tab[i] != '\0'){
printf("%c", tab[i]);
}
printf("\n");
return 0;
}

normalement dès que tab[i]='\0' comme spécifié dans ma fonction mon while devrait s'arrêter qu'en dis tu? C'est juste mon programme que je dois un peu modifier pour qu'il ne boucle plus à l'infini, bien sur je n'ai pas le droit d'utiliser strlen malheureusement...
0
{psycho.} Messages postés 101 Date d'inscription mardi 22 décembre 2009 Statut Membre Dernière intervention 4 septembre 2010 8
23 déc. 2009 à 18:58
Bon, j'arrive un peu après la guerre finalement, mais là en tout cas, ta boucle infinie vient du while présent dans ta fonction main() : tu n'incrémentes pas i :)
0
Re,

mon while devrait s'arrêter qu'en dis tu?

Il ne s'arrêtera jamais si tu n'incrémente pas le i
Dans ta boucle while i est toujours 0

while(tab[i] != '\0'){
 printf("%c", tab[i++]);
} 


Et ici ce n'est pas tableau tableau[i]='_'; mais tab
tab[i]='_'; 
0
oui psycho tu as raison, merci bcp, et un grand merci à lamij aussi, tu m'as fait découvrir l'incrémentation dans le tableau lamij merci je connaissais pas, je continue mon travail :-).
0
{psycho.} Messages postés 101 Date d'inscription mardi 22 décembre 2009 Statut Membre Dernière intervention 4 septembre 2010 8
23 déc. 2009 à 19:27
Pas de souci, pense à mettre le sujet en résolu!
Pour ce qui est des tableau, ceci dit, pour éviter de t'embêter à passer par le pointeur, tu peux directement faire comme ceci :
char  tab[][] = {"baleine","tortue","meduse"};
char *mot;
int i,j;

i = 0;
while (tab[i] != 0) //au lieu de *(tab + i)
{
  mot = tab[i];
  j = 0;
  while(mot[j] != 0)
    printf("%c", mot[j++]);
  printf("%c", '\n');
}

Et en encore plus compact...
char  tab[][] = {"baleine","tortue","meduse"};
char *mot;
int i,j;

i = -1;
while (tab[++i])
{
  j = -1
  while(mot[i][++j])
    write(1, tab[i][j], 1);
  write(1, 10, 1);  //10 = code ascii de '\n'
}
0