La boucle while
évalue l'expression: *p2++ = *p1++
. L'expression de boucle while
:
*p2 = *p1
est évaluée en utilisant le résultat de *p1
. Toutefois, cette valeur est toujours affectée à *p2
même si l'expression est évaluée comme false
ou (0)
. Réécriture ceci:
char c;
do
{
c = *p1; /* read the src byte */
*p2 = c; /* write to dst byte */
p2++, p1++; /* increment src, dst pointers */
}
while (c != 0);
Vous remarquerez qu'une lecture/écriture se produira au moins une fois. C'est OK, tant que la chaîne C p1
est terminée par zéro, et p2
a suffisamment de stockage pour la chaîne C. Cela signifie que malloc
doit allouer au moins strlen(p1) + 1
octets. Dans ce code fourni, c'est vrai.
Comme d'autres l'ont souligné, la dernière itération quittera p1
à une adresse un past-the-end, qui est encore un pointeur valide, mais a non défini des résultats quand déréférencé. L'adresse de p2
est à la fois un pointeur valide et un déréférencement valide, puisque vous allouez 20 octets. Cependant, p2
ne pointe plus vers la copie de chaîne C.Ce que vous voulez est un équivalent à:
char *p1 = "Hello";
char *p2, *tmp;
p2 = (char*)malloc (20);
memset (p2, 0, 20);
tmp = p2;
while (*tmp++ = *p1++);
printf ("%s\n", p2);
La plupart des systèmes d'exploitation libérera la mémoire à p2
à la sortie de main
, mais il est bon de se détendre les ressources avec un appel correspondant à:
free(p2);
à la fin. Alors que sur le sujet de la bonne pratique, vous devriez également vérifier la valeur de retour de malloc
pour s'assurer que l'allocation a réussi.
[Comment fonctionne "while (* s ++ = * t ++)"?] (Http://stackoverflow.com/q/810129/4279) – jfs