Problème de boucle avec deux char*.

Dreinale Messages postés 4 Statut Membre -  
Dreinale Messages postés 4 Statut Membre -
Bonjour,

J'ai un gros problème qui persiste depuis quelques heures. Je n'arrive pas a arrêter ma boucle quand je le souhaite, je veux que mon
char *bm
recopie le
char* b
et pour ça j'ai créer une boucle qui ne s'arrête que quand mon
*bm
arrive à son
'\0'
sauf que ça ne marche pas j'ai fait un peu de tout mais après ça me fait pleins de seg fault...

Voici mon code:

int test_c(char *bm)
{
    int i = 0;
    int size_read = 0;
    char *b = "9785634120";
    bm = malloc(sizeof(char) * (size_read + 1));
    while (bm[i] != b[i]) {
        bm[i] = b[i];
        i++;
        printf("%s\n", bm);
    }
    //printf("%s\n", bm);
    return (bm);
}


voila, merci.

2 réponses

  1. NHenry Messages postés 15235 Date d'inscription   Statut Modérateur Dernière intervention   387
     
    malloc alloue la mémoire, mais ne la remet pas à 0, fais un memset avant.
    Et size_read reste à 0.

    Prends l'abitude de passer en debug et d'espionner les valeurs des variables.

    2
    1. Dreinale Messages postés 4 Statut Membre
       
      D'accord merci de ta réponse, mais le problème est que je n'ai jamais utilisé memset n'y a t-il pas une autre méthode ?
      0
    2. NHenry Messages postés 15235 Date d'inscription   Statut Modérateur Dernière intervention   387
       
      Au lieu de faire
      while (bm[i] != b[i])
      fais
      while (b[i]!=0)

      mais renseignes-toi sur memset, cette fonction te sera très utile.
      0
    3. Dreinale Messages postés 4 Statut Membre
       
      d'accord merci
      0
  2. mamiemando Messages postés 33228 Date d'inscription   Statut Modérateur Dernière intervention   7 940
     
    Bonjour,

    Si l'idée est de dupliquer une chaîne dans une autre, tu devrais peut être regarder strdup.

    Et si tu veux vraiment écrire la boucle et l'arrêter quand tu découvres le caractère terminal
    '\0'
    , il faudrait plutôt écrire :

    while (*bm++ = *b++);


    Car ici ton test arrête la recopie dès que "par chance" ce qu'il y a en mémoire coïncide au niveau de
    bm[i]
    et
    b[i]
    . Or sur un
    malloc
    , où la mémoire n'est pas mise à zéro, ça engendre un comportement qui peut différer en fonction de ce qu'il y a en mémoire à cet endroit.

    Ensuite :
    - appliquer sur une chaîne qui n'est pas encore terminée par
    '\0'
    peut engendrer une erreur de segmentation
    -
    return
    est un mot clé du C, pas une fonction, donc pas besoin de parenthèse
    - merci d'utiliser les balises de code (4e bouton au dessus de la boîte dans laquelle tu tapes ton message)
    - si tu veux vraiment initialiser un bloc mémoire à zéro, tu peux utiliser
    malloc
    et
    memset
    ou plus rapidement
    calloc
    .
    - qui dit
    malloc
    (resp.
    strdup
    , resp.
    calloc
    ) dit qu'il faudra penser à faire le
    free
    correspondant.

    Bonne chance
    1
    1. [Dal] Messages postés 6122 Date d'inscription   Statut Contributeur Dernière intervention   1 108
       
      oui la fonction tiendrait en une seule ligne avec strdup sans malloc ou calloc nécessaires, ni boucle.

      https://en.cppreference.com/w/c/experimental/dynamic/strdup

      en fait, je ne suis même pas sûr que faire une fonction soit réellement utile, car il suffit de faire
      bm = strdup("9785634120");
      dans la fonction appelante au lieu d'appeler
      int test_c(char *bm)
      ...

      j'ajouterais :

      - que le
      bm = malloc(sizeof(char) * (size_read + 1));
      n'alloue qu'un seul byte (0 + 1) et que c'est ce qui provoque les segfaults en premier (Whismeril a très justement signalé que size_read reste à 0), outre les autres erreurs, puisque le code écrit dès le 2ème caractère dans une zone mémoire non allouée au programme

      - que la mise à zéro de la mémoire allouée n'est pas nécessaire si la condition de test de sortie de la boucle est correctement indiquée comme proposé par NHenry ou que la boucle while est remplacée par la solution tout en un ci-dessus de mamiemando ne nécessitant pas de corps de boucle et opérant à la fois les tests et l'incrémentiion.

      - que le
      return (bm);
      , avec ou sans parenthèses, est erroné car le prototype de la fonction exige un
      int
      en retour, et non pas un pointeur sur char et qu'il est, de toutes façons, inutile, puisque le contenu du pointeur bm modifié est accessible à la fonction appelante, en raison du passage de paramètre de la fonction.

      Dal
      0
    2. Dreinale Messages postés 4 Statut Membre
       
      D'accord merci beacoup!
      0