The while
loop is evaluating the expression: *p2++ = *p1++
. The while
loop expression:
*p2 = *p1
is evaluated using the result of *p1
. However, this value is still assigned to *p2
even if the expression evaluates as false
or (0)
. Rewriting this:
char c;
do
{
c = *p1; /* read the src byte */
*p2 = c; /* write to dst byte */
p2++, p1++; /* increment src, dst pointers */
}
while (c != 0);
You will notice that a read / write will occur at least once. That's OK, as long as the C string p1
is nul-terminated, and p2
has enough storage for the C string. That is, malloc
should allocate at least strlen(p1) + 1
bytes. In this code provided, this is true.
As others have pointed out, the final iteration will leave p1
at an address one-past-the-end, which is still a valid pointer, but has undefined results when dereferenced. The address of p2
is both a valid pointer, and a valid dereference, since you're allocating 20 bytes. However, p2
does not point to the C string copy any longer. What you want is an equivalent to:
char *p1 = "Hello";
char *p2, *tmp;
p2 = (char*)malloc (20);
memset (p2, 0, 20);
tmp = p2;
while (*tmp++ = *p1++);
printf ("%s\n", p2);
Most operating systems will release the memory at p2
on exit from main
, but it is good practice to unwind the resources with a corresponding call to:
free(p2);
at the end. While on the subject of good practice, you should also check the return value of malloc
to ensure that the allocation succeeded.