Problème de boucle avec deux char*.

Fermé
Dreinale Messages postés 4 Date d'inscription jeudi 1 novembre 2018 Statut Membre Dernière intervention 2 novembre 2018 - Modifié le 2 nov. 2018 à 00:56
Dreinale Messages postés 4 Date d'inscription jeudi 1 novembre 2018 Statut Membre Dernière intervention 2 novembre 2018 - 2 nov. 2018 à 13:50
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

NHenry Messages postés 15113 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 22 avril 2024 331
Modifié le 1 nov. 2018 à 18:10
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
Dreinale Messages postés 4 Date d'inscription jeudi 1 novembre 2018 Statut Membre Dernière intervention 2 novembre 2018
1 nov. 2018 à 19:11
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
NHenry Messages postés 15113 Date d'inscription vendredi 14 mars 2003 Statut Modérateur Dernière intervention 22 avril 2024 331
1 nov. 2018 à 20:17
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
Dreinale Messages postés 4 Date d'inscription jeudi 1 novembre 2018 Statut Membre Dernière intervention 2 novembre 2018
1 nov. 2018 à 21:43
d'accord merci
0
mamiemando Messages postés 33081 Date d'inscription jeudi 12 mai 2005 Statut Modérateur Dernière intervention 27 avril 2024 7 749
2 nov. 2018 à 00:54
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
[Dal] Messages postés 6174 Date d'inscription mercredi 15 septembre 2004 Statut Contributeur Dernière intervention 2 février 2024 1 083
Modifié le 2 nov. 2018 à 13:56
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
Dreinale Messages postés 4 Date d'inscription jeudi 1 novembre 2018 Statut Membre Dernière intervention 2 novembre 2018
2 nov. 2018 à 13:50
D'accord merci beacoup!
0