Please study this inexplicable behavior and memcpy () output for overlapping memory blocks

After reading the following about memcpy() , I started reading 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 out the program used to illustrate memmove() , I decided to configure it using memcpy() instead to see how different the output is. To my surprise, they are the same even if this is a case of overlapping memory blocks. Here is the program and conclusion, and I began to describe my confusion after this:

 #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; } 

Exit memmove can be very very useful.

This output is the same as for memmove() . And here are my confusions:

1) Why is the conclusion the same for both? Since the intermediate buffer is not used in the case of memcpy() , I expect the copy to start by copying the character at position str+15 str+20 position (overwriting what is), the character at position str+16 to position str+21 and t .d. to the character at str + 20, which has now changed to the character at str + 15, to copy to str + 25 . But this is not so, there is no rewriting and acts as if the intermediate buffer was used to write the exact source string. Here is 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 does memcpy () copy it as memmove can be very useful , instead of memmove it can be very very v ?

2) Now a minor secondary question arises related to this. The following is about memmove() ( LINK )

Copying takes place as if an intermediate buffer were used, allowing the destination and source to overlap.

What is as if here? Is the intermediate buffer really used for memmove() ?

-1
source share
1 answer

If objects overlap, memcpy's behavior is undefined. There is little point in trying to talk about undefined behavior. Since it is undefined, it challenges the reason. You know the rules, and they are clearly documented. If objects overlap, use memmove.

As for the use of โ€œas ifโ€, that is, to indicate behavior, but not to limit any restrictions. This allows the library developer to use any method that they consider appropriate if the end result matches the use of an intermediate buffer. For example, an implementation may find that objects do not overlap, and therefore avoid using an intermediate buffer for performance reasons.

+6
source

Source: https://habr.com/ru/post/1480708/


All Articles