[C] Erreur de segmentation

Répondre
Partager Rechercher
B'jour/'soir,
j'ai un petit problème de segmentation dans mon programme , le code source :

Code PHP:

#include <stdio.h>
  #include <string.h>
  
  
void supp_esp(char x[],char y[])
  {
      
int length,0;
      for(
i=0;i<strlen(x);i++)
          {
          if (
x[i] != 32)
              {
              
y[length] = x[i];
              
length++;
              }
          }
      
/*for(;length<strlen(y);length++)
          {
          y[length] = 32;
          }*/
  
}
      
  
int main()
  {
      
char a[] ="Bonjour ca va bien ?";
      
char b[strlen(a)];
      
supp_esp(a,b);
      
printf("%d %d\n",strlen(a),strlen(b));
      
      return 
0;
  } 
Ce programme est censé lire une chaine de caractère x de taille inconnu , supprimer les espaces en la copiant dans y.

Desespèrement,
moi.
length n'est pas initialisé. Pour peu que tu n'aies pas de bol (genre 9 fois sur 10), le compilo va lui donner une valeur différente et probablement pas dans les bornes de ta chaine de caractère.

int length,i = 0;

permet juste de déclarer length et i en int, et de donner à i la valeur 0. Pour initialiser les deux il faut

int length =0, i =0;

(perso je conseillerais volontier de séparer les lignes de déclarations).
La réponse est donnée donc.
Je rajouterai juste:
- à la fin de la boucle for de la fonction supp_esp, faire un y[length]='\n'.
- transformer le x[i]!=32 en x[i]!=' ' qui me semble plus propre et moins dépendant.

La deuxième boucle, mise en commentaire, ne sert à rien, elle remplit juste la fin de la chaine par des caractères vides, ce qui ne sert à rien (une fois que le \n a été mis)
Citation :
Publié par Anduric
Pour initialiser les deux il faut

int length =0, i =0;
Merci , ca fonctionne a présent


Citation :
Publié par Zeil l'exilé
- à la fin de la boucle for de la fonction supp_esp, faire un y[length]='\n'.
Je pense que tu voulais dire :
Code PHP:

   y[length]='\0'
Merci de m'y avoir fait pensé , c'est beaucoup plus simple comme ça


Citation :
Publié par Zeil l'exilé
- transformer le x[i]!=32 en x[i]!=' ' qui me semble plus propre et moins dépendant.
Euh , j'ai pas compris là , de plus gcc refuse de compiler
Ah mon avis le i<strlen(x) est un peu pourri.
Si j'interprete bien, a chaque passage tu vas calculer la taille de la chaine qui est pourtant constante.

c'est pas tres optimisé quoi
Il faudrait la mettre dans une variable avant...
ou...
j'aurais fait comme ca:

i=
length=0;
while (x[i]) {
if (x[i] != 32) y[length++] = x[i++];
else i++;
}
*y=0;


Sereg a raison : strlen est O(n) - ou n est le nombre de caractères. Faire n fois strlen donne donc un algo en O(n²) alors qu'il est faisable en O(n).

Ton camarade voulait remplacer 32 par '<espace>' et pas par ''
Tu passes en paramètre des tableaux sans indiquer leur taille. C'est dangereux, il y a un risque de buffer overflow (ici, si la taille du 2e tableau n'est pas suffisante). Il faudrait ajouter dans les arguments la taille du buffer y.

De plus, comme ça a été signalé, ton code appelle en boucle strlen alors que c'est inutile.

Par exemple :
Code:
/*recopie x dans y, en omettant les espaces*/
void supp_esp(char x[], char y[], unsigned int size_y)
{
    unsigned int xi, yi;
    for (xi = 0, yi = 0; yi < size_y; xi++)
    {
        if (x[xi] == '\0')
            return;
        if (x[xi] == ' ')
            continue;
        y[yi] = x[xi];
        yi++;
        /*on pourrait mettre le ++ dans la ligne précédente, mais c'est plus
         *lisible comme ça : pas besoin de se poser de question de
         *pré ou post incrémentation, et pas de risque de se tromper.
         */
    } 
}
Remontage de sujet
Je me permets de remonter ce sujet bien :

Mon code source:
Code PHP:

#include <stdio.h>
  
  // Définition des variables globales
  
float prix[3] = {1.0,1.2,1.5};
  
int stock_canettes[3]={10,20,30};
  
  
float pieces[5] = {0.1,0.2,0.5,1.0,2.0};
  
int stock_pieces[2][5] = {250,200,200,150,100,500,400,400,300,200};
  
  
void stats()
  {
  
int i;
  
printf("pieces :\n");
  for(
i=0;i<5;i++)
      
printf("%d/%d ",stock_pieces[0][i],stock_pieces[1][i]);
  
printf("\n");
  
printf("canette :\n");
  for(
i=0;i<3;i++)
      
printf("%d ",stock_canettes[i],stock_canettes[i]);
  
printf("\n");
  }
  
  
int main()
  {
  
  
stats();
  
  return 
0;
  } 
et ce que me dit gcc lors de la compilation :
Citation :
main.c:8: attention : accolades manquantes autour de l'initialisation
main.c:8: attention : (near initialization for ‘stock_pieces[0]’)
main.c: In function ‘stats’:
main.c:19: attention : trop d'arguments pour le format
J'aimerai bien comprendre les avertissements de la ligne 8 ainsi que ceux se rapportant à la fonction stats
Salut

Pour la ligne 8, c'est parce que tu déclares un tableau à deux dimensions, mais lors de son initialisation, tu donnes un tableau à une seule dimension.
A la ligne 19, ton printf a un seul %d alors qu'il y a deux arguments suivants, ce que tu veux faire est sans doute:
Code PHP:

printf("%d ",stock_canettes[i]); 

ou
Code PHP:

printf("%d %d",stock_canettes[i], stock_canettes[i]); 

Pour la ligne 8:
int stock_pieces[2][5] = {{250,200,200,150,100},{500,400,400,300,200}};
est correct.

Pour le reste, je ne vois pas trop, peut-être qu'il aime le typage fort.

Essaye de spécifier: void stat(void)

De même qu'au-dessus pour le printf, ce n'est pas une erreur mais cela ne sert à rien.

edit: je rajouterai qu'il faut éviter les variables globales pour deux raisons:

1) Pour bien connaitre le C, l'utilisation des pointeurs est impérative.
2) Cela peut entrainer des effets de bords indésirables.


Bon amusement avec le problème du "retour de la monnaie", c'est d'un ennui profond
Citation :
Publié par Zeil l'exilé
Pour le reste, je ne vois pas trop, peut-être qu'il aime le typage fort. Essaye de spécifier: void stat(void)
Citation :
main.c: In function ‘stats’:
main.c:19: attention : trop d'arguments pour le format
Je pense pas que le warning porte sur la signature de stats, les 2 lignes doivent être lues ensemble: dans la fonction stats il y a un warning ligne 19. Ce ne sont pas 2 warnings différents.
C'est pareil quand il y a des erreurs, il précise généralement dans quelle fonction se trouve l'erreur.
Donc gcc te précise simplement 2 warnings: un à la ligne 8 et un à la ligne 19.
Merci à Zeil pour l'erreur de la ligne 8 et à Ze Reaper pour l'erreur de la ligne 19
Vous éloignez pas trop de JoL , je risque de remonter ce sujet si je suis bloqué sur mon super projet que Zeil connaît apparemment

PS : quelle merde la fonction getchar() , ca vide même pas le buffer , ca fait qu'il faut que je vérifie à chaque fois si il reste un LF ou pas
Répondre

Connectés sur ce fil

 
1 connecté (0 membre et 1 invité) Afficher la liste détaillée des connectés