What is the difference between memmove
and memcpy
? Which one do you usually use and how?
views:
1833answers:
5From 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.
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.
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
The technical difference has been documented pretty well by previous answers. The practical differences should be noted as well:
Memcpy will need approximately twice the amount of memory to perform the same task, but memmove could take significantly longer than memcpy.
Example:
Say you have a list of 100 items in memory, taking 100 MBs of memory. You want to drop the 1st item so you only have 99.
Memcpy will require the original 100 MBs and an additional 99 MBs for your new list of 99 items. Approximately 199 MBs total to perform the operation, but should be very fast.
Memmove, in the worst scenario will require the original 100 MBs, and will move every item 1 memory address up at a time. This only requires the original 100 MBs, but will be significantly slower than Memcpy.
Of course, creating a new pointer to point at the 2nd item in your list will achieve the same effect of "dropping" the first item from your list, but the example shows the differences in memcpy and memmove well.
-- EDIT TO HELP CLARIFY MY CRAPPY ANSWER --
Yes, the implementations of memcpy() and memmove() probably don't differ in memory usage (I really don't know), but how you use them will greatly effect the memory usage of your program. That is what I meant by practical differences of memcpy() and memmove().
int SIZE = 100;
Item *ptr_item = (Item *) malloc(size_of(Item) * SIZE);
Item *ptr_src_item = ptr_item + 1;
Item *ptr_dst_item = ptr_item;
memmove(ptr_dst_item, ptr_src_item, SIZE - 1);
This creates your list of Items with the first Item missing. This essentially requires no more memory for your program than what it takes to allocate the original ptr_item block of memory. You can't do this using memcpy()...if you did, your program would need to allocate about twice as much memory.
int SIZE = 100;
Item *ptr_src_item = (Item *) malloc(size_of(Item) * SIZE);
Item *ptr_dst_item = (Item *) malloc(size_of(Item) * (SIZE - 1));
memcpy(ptr_dst_item, ptr_src_item, SIZE - 1);
In this second block of code, the program would require twice as much memory as the first block. However, this second block should perform significantly faster than the first block, especially as SIZE increases.
That's how I was trying to explain the practical differences in the two...but perhaps I'm wrong with this as well?