What is happening is that you're malloc
ing two memory blocks. Those blocks have address, which d
and e
holds. To confirm that, put these after your scanf
s.
printf ("Address of d: %p\n", &d);
printf ("Address of e: %p\n", &e);
printf ("Address of block d(value of d): %p\n", d);
printf ("Address of block e(value of e): %p\n", e);
My output is:
Address of d: 0x7fff037a5488
Address of e: 0x7fff037a5490
Address of block d(value of d): 0xa8e010
Address of block e(value of e): 0xa8e030
Now, when you make the swap between the pointers, all you're doing is changing the memory block references, not the actual pointer address (which you can't do).
You can confirm that by putting those printf
after the swaps, like this:
#include<stdio.h>
#include<stdlib.h>
int main()
{
char *d,*e,*f;
d=(char*)malloc(10);
e=(char*)malloc(5);
scanf("%s",d);
scanf("%s",e);
printf ("Address of d: %p\n", &d);
printf ("Address of e: %p\n", &e);
printf ("Address of f: %p\n", &f);
printf ("Address of block d(value of d): %p\n", d);
printf ("Address of block e(value of e): %p\n", e);
f=d;
d=e;
e=f; //while printing e it prints the whole value contained in f (i.e.1ellohai). How? size of e is 5 only
printf ("Address of d: %p\n", &d);
printf ("Address of e: %p\n", &e);
printf ("Address of f: %p\n", &f);
printf ("Address of block d(value of d): %p\n", d);
printf ("Address of block e(value of e): %p\n", e);
printf ("Address of block f(value of f): %p\n", f);
f[0]='1'; // f is in read-only memory. So this should fail?
printf("%s \t %s \t %s \n",d,e,f);
return 0;
}
And the output:
$ ./draft
hellohai
asd
Address of d: 0x7ffebae87d78
Address of e: 0x7ffebae87d80
Address of f: 0x7ffebae87d88
Address of block d(value of d): 0x2143010
Address of block e(value of e): 0x2143030
Address of d: 0x7ffebae87d78
Address of e: 0x7ffebae87d80
Address of f: 0x7ffebae87d88
Address of block d(value of d): 0x2143030
Address of block e(value of e): 0x2143010
Address of block f(value of f): 0x2143010
asd 1ellohai 1ellohai
From this you can see that:
-
- The addresses of the pointers never changed.
-
- The references (their values) changed. They got swaped.
-
e
and f
point to the same memory block. That's why doing f[0]='1'
changes the value printed by both.
A primitive memory layout
After you declare your variables, you memory will look like this:
Values : | - | - | - | | | |
Variable : | d | e | f | | | |
Memory(hex): | 1 | 2 | 3 | 4 | 5 | 6 |
When you malloc, your computer gives d
the block at address 5 and e
the block at address 6, so now it looks like this:
Values : | 5 | 6 | - | | | |
Variable : | d | e | f | | | |
Memory(hex): | 1 | 2 | 3 | 4 | 5 | 6 |
After you read your strings, the contents of the blocks at 5 and 6 will get written:
Values : | 5 | 6 | - | | hellohai | asd |
Variable : | d | e | f | | | |
Memory(hex): | 1 | 2 | 3 | 4 | 5 | 6 |
When you print d
, it access the memory address it points to (5 in this case) and print the contents. Same for the e
variable.
Now, when you swap the values doing:
f=d;
Values : | 5 | 6 | 5 | | hellohai | asd |
Variable : | d | e | f | | | |
Memory(hex): | 1 | 2 | 3 | 4 | 5 | 6 |
d=e;
Values : | 6 | 6 | 5 | | hellohai | asd |
Variable : | d | e | f | | | |
Memory(hex): | 1 | 2 | 3 | 4 | 5 | 6 |
e=f;
Values : | 6 | 5 | 5 | | hellohai | asd |
Variable : | d | e | f | | | |
Memory(hex): | 1 | 2 | 3 | 4 | 5 | 6 |
Now e
and f
point to the same place (where d
used to point) and d
points to where e
used to point. It's important to note that the actual values of the addresses 5 and 6 never got touched.
And when you do:
f[0]='1';
You're telling the computer to access the first byte of the contents of the memory block at address 5 and change it. So now you have:
Values : | 6 | 5 | 5 | | 1ellohai | asd |
Variable : | d | e | f | | | |
Memory(hex): | 1 | 2 | 3 | 4 | 5 | 6 |
This is a very simple representation of what you memory might look like so you can get the idea of how it works.