After reading the following about memcpy()
, I proceeded to read about memmove()
:
To avoid overflows, the size of the arrays pointed by both the destination and source parameters, shall be at least num bytes, and should not overlap (for overlapping memory blocks, memmove is a safer approach).
(LINK)
And after checking the program used to illustrate the working of memmove()
I decided to tweak it by using memcpy()
instead to see how different is the output.To my surprise,they are the same even if it's a case of overlapping memory blocks.Here is the program and the output,and I have proceeded to describe my confusion after that:
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "memmove can be very useful......";
//memmove (str+20,str+15,11);
memcpy(str+20,str+15,11); //Simply used memcpy instead of memmove
puts (str);
return 0;
}
Output memmove can be very very useful.
This output is the same as it is for memmove()
.And here are my confusions:
1) Why is output same for both?Since there is no intermediate buffer used in case of memcpy()
,I expect the copy to start by copying the character in str+15
position to the str+20
position (overwriting what is there),character in str+16
position to str+21
position, and so on till character in str+20 position,which has by now changed to the character in str+15 position, to be copied to the str+25 position.But it's not so,there is no overwriting and it's acting as if an intermediate buffer is used to write the exact original string.Here's an illustration:
memmove can be very useful...... //Original positions before memcopy
^ ^
str+15 str+20
memmove can be very vseful......
^ copies str+15 to str+20
memmove can be very veeful......
^ copies str+16 to str+21
memmove can be very verful......
^ copies str+17 to str+22
memmove can be very veryul......
^copies str+18 to str+23
memmove can be very very l......
^ copies str+19 to str+24
memmove can be very very v......
^ I expect 'v' to be copied from str+20 to str+25
as str+20 now has 'v',not 'u'
memmove can be very very ve.....
^ I expect 'e' to be copied from str+21 to str+26
as str+21 now has 'e' not 's'
Then why is memcpy() copying it as memmove can be very very useful, instead of memmove can be very very very v ?
2) Now a minor secondary question arising from it.The following is said about memmove()
(LINK)
Copying takes place as if an intermediate buffer were used, allowing the destination and source to overlap.
What exactly is as if
here?Isn't an intermediate buffer really used for memmove()
?
str+20
to be overwritten. – Raddledmemcpy
is a constant,why are we even allowed to write onto that without generating errors formemcpy()
? – Raddledconst int i = 10;
......int *ptr = &i;
..*ptr = 100;
..printf("%d",i)
. which is UB. but i broke the covenant. compiler warns but i can do it. you cant even be sure wherther it will print – Mow