Before the loop starts the dp points to the start of the memory you have allocated. At each iteration you copy the character pointed by src into the currently pointed location of dp and step forward one memory location pointed by dp. At the end of the loop dp is pointing at the memory location right after the character p where you have assigned a '\0'. When you attempt to print the string with puts (dp) because the contents of dp has changed and now points to a location right after the last character copied, it will start printing from that location. It will print an empty string as the very first location pointed by dp is a null character.
Before Loop
+----------+
| src |
+----------+
|
|
V
+-----+-----+-----+-----+-----+-----+-----+---- ----+----+
| h | t | t | p | : | / | / | . . . ? | ? |
+-----+-----+-----+-----+-----+-----+-----+---- ----+----+
+----------+
| dp |
+----------+
|
|
V
+-----+-----+-----+-----+-----+-----+-----+---- ----+----+
| | | | | | | | . . . | |
+-----+-----+-----+-----+-----+-----+-----+---- ----+----+
After Loop (with dp = malloc (10))
+----------+
| src |
+----------+
|
|
V
+-----+-----+-----+-----+-----+-----+-----+---- ----+----+
| h | t | t | p | : | / | / | . . . | ? |
+-----+-----+-----+-----+-----+-----+-----+---- ----+----+
+----------+
| dp |
+----------+
|
|
V
+-----+-----+-----+-----+-----+-----+-----+---- ----+----+
| h | t | t | p | \0 | | | . . . | |
+-----+-----+-----+-----+-----+-----+-----+---- ----+----+
Note puts (dp) will start printing print from the location pointed above.
This will not get the intended output. Also because you have not saved the
original address of dp which you have actually allocated. You are not able
to restore it after the loop.
After Loop (with dp = &scheme)
+----------+
| src |
+----------+
|
|
V
+-----+-----+-----+-----+-----+-----+-----+---- ----+----+
| h | t | t | p | : | / | / | . . . | ? |
+-----+-----+-----+-----+-----+-----+-----+---- ----+----+
+----------+
| dp |
+----------+
|
|
V
+-----+-----+-----+-----+-----+-----+-----+---- ----+----+
scheme[ | h | t | t | p | \0 | | | . . . | | ]
+-----+-----+-----+-----+-----+-----+-----+---- ----+----+
puts (scheme) will work because it still refers to the base of the array
puts (dp) will not work because it does not point to the base of the array
and currently points to a location pointing to null character
In the above commented solution of yours works because, you use the scheme array to print the string. scheme refers to the array you want to print and scheme refers to the base address of the array because you have not modified it (and it cannot be modified). This is why it starts from the base and prints upto the '\0' you have assigned after the loop.
You can either do
int i;
for (i=0; (src[i] != ':') && (src[i] != '\0'); i++)
{
dp[i] = src[i];
}
or do the below
char *dp_bak;
char *dp = malloc(10);
dp_bak = dp; /* Backup the base address */
while (*src != ':')
{
*dp = *src;
src++;
dp++;
}
*dp = '\0';
dp = db_bak; /* Restore the base address */
puts (dp);