What is the difference between memmove and memcpy?

CMemcpyMemmove

C Problem Overview


What is the difference between memmove and memcpy? Which one do you usually use and how?

C Solutions


Solution 1 - C

With memcpy, the destination cannot overlap the source at all. With memmove it can. This means that memmove might be very slightly slower than memcpy, as it cannot make the same assumptions.

For example, memcpy might always copy addresses from low to high. If the destination overlaps after the source, this means some addresses will be overwritten before copied. memmove would detect this and copy in the other direction - from high to low - in this case. However, checking this and switching to another (possibly less efficient) algorithm takes time.

Solution 2 - C

memmove can handle overlapping memory, memcpy can't.

Consider

char[] str = "foo-bar";
memcpy(&str[3],&str[4],4); //might blow up

Obviously the source and destination now overlap, we're overwriting "-bar" with "bar". It's undefined behavior using memcpy if the source and destination overlap so in this case cases we need memmove.

memmove(&str[3],&str[4],4); //fine

Solution 3 - C

From the http://linux.die.net/man/3/memcpy">memcpy</a> man page.

> The memcpy() function copies n bytes > from memory area src to memory area > dest. The memory areas should not > overlap. Use http://linux.die.net/man/3/memmove">memmove</a>(3) if the memory > areas do overlap.

Solution 4 - C

Assuming you would have to implement both, the implementation could look like that:

void memmove ( void * dst, const void * src, size_t count ) {
    if ((uintptr_t)src < (uintptr_t)dst) {
        // Copy from back to front

    } else if ((uintptr_t)dst < (uintptr_t)src) {
        // Copy from front to back
    }
}

void memcpy ( void * dst, const void * src, size_t count ) {
    if ((uintptr_t)src != (uintptr_t)dst) {
        // Copy in any way you want
    }
}

And this should pretty well explain the difference. memmove always copies in such a way, that it is still safe if src and dst overlap, whereas memcpy just doesn't care as the documentation says when using memcpy, the two memory areas must not overlap.

E.g. if memcpy copies "front to back" and the memory blocks are aligned as this

[---- src ----]
            [---- dst ---]

copying the first byte of src to dst already destroys the content of the last bytes of src before these have been copied. Only copying "back to front" will lead to correct results.

Now swap src and dst:

[---- dst ----]
            [---- src ---]

In that case it's only safe to copy "front to back" as copying "back to front" would destroy src near its front already when copying the first byte.

You may have noticed that the memmove implementation above doesn't even test if they actually do overlap, it just checks their relative positions, but that alone will make the copy safe. As memcpy usually uses the fastest way possible to copy memory on any system, memmove is usually rather implemented as:

void memmove ( void * dst, const void * src, size_t count ) {
    if ((uintptr_t)src < (uintptr_t)dst
        && (uintptr_t)src + count > (uintptr_t)dst
    ) {
        // Copy from back to front

    } else if ((uintptr_t)dst < (uintptr_t)src
        && (uintptr_t)dst + count > (uintptr_t)src
    ) {
        // Copy from front to back

    } else {
        // They don't overlap for sure
        memcpy(dst, src, count);
    }
}

Sometimes, if memcpy always copies "front to back" or "back to front", memmove may also use memcpy in one of the overlapping cases but memcpy may even copy in a different way depending on how the data is aligned and/or how much data is to be copied, so even if you tested how memcpy copies on your system, you cannot rely on that test result to be always correct.

What does that mean for you when deciding which one to call?

  1. Unless you know for sure that src and dst don't overlap, call memmove as it will always lead to correct results and is usually as fast as that is possible for the copy case you require.

  2. If you know for sure that src and dst don't overlap, call memcpy as it won't matter which one you call for the result, both will work correctly in that case, but memmove will never be faster than memcpy and if you are unlucky, it may even be slower, so you can only win calling memcpy.

Solution 5 - C

The main difference between memmove() and memcpy() is that in memmove() a buffer - temporary memory - is used, so there is no risk of overlapping. On the other hand, memcpy() directly copies the data from the location that is pointed by the source to the location pointed by the destination. (http://www.cplusplus.com/reference/cstring/memcpy/)

Consider the following examples:

    #include <stdio.h>
    #include <string.h>

    int main (void)
    {
        char string [] = "stackoverflow";
        char *first, *second;
        first = string;
        second = string;

        puts(string);
        memcpy(first+5, first, 5);
        puts(first);
        memmove(second+5, second, 5);
        puts(second);
        return 0;
    }


As you expected, this will print out:

    stackoverflow
    stackstacklow
    stackstacklow

2. But in this example, the results will not be the same:

    #include <stdio.h>
    #include <string.h>

    int main (void)
    {
        char string [] = "stackoverflow";
        char *third, *fourth;
        third = string;
        fourth = string;

        puts(string);
        memcpy(third+5, third, 7);
        puts(third);
        memmove(fourth+5, fourth, 7);
        puts(fourth);
        return 0;
    }

Output:

    stackoverflow
    stackstackovw
    stackstackstw

It is because "memcpy()" does the following:

1.	stackoverflow
2.	stacksverflow
3.	stacksterflow
4.	stackstarflow
5.	stackstacflow
6.	stackstacklow
7.	stackstacksow
8.	stackstackstw

Solution 6 - C

One (memmove) handles overlapping destinations the other (memcpy) doesn't.

Solution 7 - C

simply from the ISO/IEC:9899 standard it is well described.

>7.21.2.1 The memcpy function > >[...] > >2 The memcpy function copies n characters from the object pointed to by s2 into the object pointed to by s1. If copying takes place between objects that overlap, the behavior is undefined.

And

>7.21.2.2 The memmove function > >[...] > >2 The memmove function copies n characters from the object pointed to by s2 into the object pointed to by s1. Copying takes place as if the n characters from the object pointed to by s2 are first copied into a temporary array of n characters that does not overlap the objects pointed to by s1 and s2, and then the n characters from the temporary array are copied into the object pointed to by s1.

Which one I usually use acording to the question, depends on what functionallity I need.

In plain text memcpy() doesn't allow s1 and s2 to overlap, while memmove() does.

Solution 8 - C

There are two obvious ways to implement mempcpy(void *dest, const void *src, size_t n) (ignoring the return value):

  1.  for (char *p=src, *q=dest;  n-->0;  ++p, ++q)
         *q=*p;
    
  2.  char *p=src, *q=dest;
     while (n-->0)
         q[n]=p[n];
    

In the first implementation, the copy proceeds from low to high addresses, and in the second, from high to low. If the range to be copied overlaps (as is the case when scrolling a framebuffer, for example), then only one direction of operation is correct, and the other will overwrite locations that will subsequently be read from.

A memmove() implementation, at its simplest, will test dest<src (in some platform-dependent way), and execute the appropriate direction of memcpy().

User code can't do that of course, because even after casting src and dst to some concrete pointer type, they don't (in general) point into the same object and so can't be compared. But the standard library can have enough platform knowledge to perform such a comparison without causing Undefined Behaviour.


Note that in real life, implementations tend to be significantly more complex, to gain the maximum performance from larger transfers (when alignment permits) and/or good data cache utilisation. The code above is just to make the point as simply as possible.

Solution 9 - C

memmove can deal with overlapping source and destination regions, while memcpy cannot. Among the two, memcpy is much more efficient. So, better to USE memcpy it if you can.

Reference: https://www.youtube.com/watch?v=Yr1YnOVG-4g Dr. Jerry Cain, (Stanford Intro Systems Lecture - 7) Time: 36:00

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionultramanView Question on Stackoverflow
Solution 1 - CbdonlanView Answer on Stackoverflow
Solution 2 - CnosView Answer on Stackoverflow
Solution 3 - CJohn CarterView Answer on Stackoverflow
Solution 4 - CMeckiView Answer on Stackoverflow
Solution 5 - CMirac SuzgunView Answer on Stackoverflow
Solution 6 - CKPexEAView Answer on Stackoverflow
Solution 7 - CdheinView Answer on Stackoverflow
Solution 8 - CToby SpeightView Answer on Stackoverflow
Solution 9 - CEhsanView Answer on Stackoverflow