What is the difference between memmove
and memcpy
? Which one do you usually use and how?
9 Answers
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.
-
1when using memcpy, how can I guarantee that the src and dest addresses don't overlap? Should I personally make sure that src and dest do not overlap? – Alcott Sep 09 '11 at 13:08
-
8@Alcott, don't use memcpy if you don't know that they don't overlap - use memmove instead. When there is no overlap, memmove and memcpy are equivalent (although memcpy might be very, very, very slightly faster). – bdonlan Sep 09 '11 at 21:33
-
You can use 'restrict' keyword if you are working with long arrays and want to protect your copying process. For example if you method takes as parameters input and output arrays and you must verify that user does not pass the same address as input and output. Read more here http://stackoverflow.com/questions/776283/what-does-the-restrict-keyword-mean-in-c – DanielHsH Jan 01 '15 at 10:46
-
11@DanielHsH 'restrict' is a promise you make the compiler; it is not _enforced_ by the compiler. If you put 'restrict' on your arguments and do, in fact, have overlap (or more generally, access the restricted data from pointer derived from multiple places), the behavior of the program is undefined, weird bugs will happen, and the compiler will usually not warn you about it. – bdonlan Feb 09 '15 at 06:34
-
@bdonlan It's not just a promise to the compiler, it's a requirement for your caller. It's a requirement that is not enforced but if you violate a requirement, you cannot complain if you get unexpected results. Violating a requirement is undefined behavior, just like `i = i++ + 1` is undefined; the compiler doesn't forbid you to write exactly that code but the result of that instruction can be anything and different compilers or CPUs will show different values here. – Mecki Apr 14 '18 at 22:16
-
-
@Mecki "not enforced" and "requirement" don't go together. It seems you're saying the same thing as bdonlan once we strip the first two contradictory sentences away. – iheanyi Aug 05 '21 at 05:23
-
@iheanyi They do go together as requirement means "it is required to do it that way if you want to have correct results" but getting correct results is **not enforced**. Of course you can write code that produces incorrect results if you like. – Mecki Aug 05 '21 at 08:36
-
@Mecki I disagree. If that's the definition of "requirement", then it means nothing. You can write code that doesn't compile too if you'd like. There's no compiler that forces anyone to do anything they don't want to do. – iheanyi Aug 05 '21 at 17:21
-
@iheanyi No, you don't. You just repeated what I've said. A requirement in behavior does not mean that you cannot behave in a different way, it only means that behaving a different way has consequences. It is a requirement to follow the law but you can also violate it. If something is made in such a way, that you cannot violate it, then no requirement is necessary as there is no choice; you have to do it in the only way possible so what would be the requirement then? Not doing it that way means not doing it at all. – Mecki Aug 05 '21 at 18:32
-
1@Mecki then I don't see the difference between your comment and bdonlan. It seems you are saying the same thing. Restrict is a promise made to the compiler. But the compiler will let you violate that promise with potentially undefined results. Replace "promise" with "requirement" and you are saying the same thing. – iheanyi Aug 05 '21 at 21:03
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 we need memmove
.
memmove(&str[3], &str[4], 4); // fine
-
5@ultraman: Because it MAY have been implemented using low level assembley that requires that memory does not overlap. If it does you could for example generate a signal or hardware exception to the processor that aborts the application. The documentation specifies that it does not handle the condition, but the standard does not specify what will happen when these conditions are vialoated (this is known as undefined behavior). Undefined behavior can do anything. – Martin York Jul 29 '09 at 17:21
-
1with gcc 4.8.2 , Even memcpy also accepts overlapping source and destination pointers and working fine. – Jagdish Jun 26 '15 at 02:18
-
7@jagsgediya Sure it might. But since memcpy is documented to not support this, you should not rely on that implementation specific behavior, that's why memmove() exist. It might be different in another version of gcc. It might be different if gcc inlines the memcpy instead of calling out to memcpy() in glibc, it might be different on an older or newer version of glibc and so on. – nos Jun 26 '15 at 08:32
-
From practice, it seems the memcpy and memmove did the same thing. Such a deep undefined behavior. – Life Feb 08 '16 at 22:52
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?
Unless you know for sure that
src
anddst
don't overlap, callmemmove
as it will always lead to correct results and is usually as fast as that is possible for the copy case you require.If you know for sure that
src
anddst
don't overlap, callmemcpy
as it won't matter which one you call for the result, both will work correctly in that case, butmemmove
will never be faster thanmemcpy
and if you are unlucky, it may even be slower, so you can only win callingmemcpy
.

- 125,244
- 33
- 244
- 253
-
4+1 because your "ascii drawings" were useful to understand why there may not be overlapping without corrupting the data – Scylardor Jul 17 '19 at 19:08
-
Note that the result of relational comparing pointers to different objects/arrays is unspecified. So there is no way to safely detect if two objects overlay with each other. In fact, the typical implementation of `memmove` copies data from front to back if `dst < src` otherwise copies data from back to front. It is safe because if there's overlay, the result is defined(and correct) so the behavior is safe, otherwise if there's no overlay, the result is unspecified but copying in both directions is safe. – VainMan Sep 24 '20 at 01:15
From the memcpy man page.
The memcpy() function copies n bytes from memory area src to memory area dest. The memory areas should not overlap. Use memmove(3) if the memory areas do overlap.

- 53,924
- 26
- 111
- 144
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
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

- 27,591
- 48
- 66
- 103

- 155
- 1
- 6
-
3
-
1When I run the same program , I get the following result : stackoverflow stackstackstw stackstackstw // means there is NO difference in output between memcpy and memmove – kumar Nov 20 '14 at 16:16
-
8"is that in "memmove()", a buffer - a temporary memory - is used;" Is not true. it says "as if" so it just has to behave so, not that it has to be that way. Thats indeed relevant as most memmove implementations just do a XOR-swap. – dhein May 08 '15 at 11:25
-
5I don't think the implementation of `memmove()` is required to use a buffer. It's perfectly entitled to move in-place (as long as each read completes before any write to the same address). – Toby Speight May 20 '16 at 10:54
One (memmove
) handles overlapping destinations the other (memcpy
) doesn't.

- 2,614
- 1
- 12
- 30

- 16,560
- 16
- 61
- 78
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.
There are two obvious ways to implement mempcpy(void *dest, const void *src, size_t n)
(ignoring the return value):
for (char *p=src, *q=dest; n-->0; ++p, ++q) *q=*p;
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.

- 27,591
- 48
- 66
- 103
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

- 1,338
- 14
- 13
-
1[This answer](http://stackoverflow.com/a/28624068/2410359) says "possibly a smidge faster" and provides quantitative data indicating only a slight difference. This answer asserts one is "much more efficient". How much more efficient have you found the faster one to be? BTW: I assume you mean `memcpy()` and not `memcopy()`. – chux - Reinstate Monica Dec 10 '16 at 03:14
-
The comment is made based on the lecture of Dr. Jerry Cain. I would request you listen to his lecture at time 36:00, only 2-3 minutes will suffice. And thanks for the catch. :D – Ehsan Dec 10 '16 at 03:45