memcpy vs memmove
【本文连接】
http://www.cnblogs.com/hellogiser/p/memcpy_vs_memmove.html
【分析】
memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。
但当源内存和目标内存存在重叠(memory overlapping)时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销。
memmove的处理措施:
(1)当源内存的首地址等于目标内存的首地址时,不进行任何拷贝
(2)当源内存的首地址大于目标内存的首地址时,实行正向拷贝
(3)当源内存的首地址小于目标内存的首地址时,实行反向拷贝
示意图:
(1)内存低端 <-----s-----> <-----d-----> 内存高端 start at end of s
(2)内存低端 <-----s--<==>--d-----> 内存高端 start at end of s
(3)内存低端 <-----sd-----> 内存高端 do nothing
(4)内存低端 <-----d--<==>--s-----> 内存高端 start at beginning of s
(5)内存低端 <-----d-----> <-----s-----> 内存高端 start at beginning of s
【代码】
C++ Code
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 |
#include <stdio.h>
#include <stdlib.h> #include <string.h> #include <iostream> using namespace std; /* * not check overlapping * optimization: copy by word(4 or 8 bytes) instead of by 1 byte * */ void* my_memcpy(void* dest,const void* src,size_t count) { if(src == NULL || dest == NULL) return NULL; char* d = (char*)dest; const char* s = (const char*)src; while(count--) { *d ++ = *s ++; } return dest; } /* * check overlapping * optimization: copy by word(4 or 8 bytes) instead of by 1 byte * */ /* * d == s * d <s, copying from the beginning * d >s, copying from the end * */ void* my_memmove(void* dest,const void* src,size_t count) { if(src == NULL || dest == NULL) return NULL; char* d = (char*)dest; const char* s = (const char*)src; if(d<s) { //copy from the beginning while(count--) { *d++ = *s++; } } else if(d>s) { //copy from the end d = d+count-1; s = s+count-1; while(count--) { *d-- = *s--; } } else { // do nothing } return dest; } void test_case() { char dest[100]; const char *src = "hello"; my_memcpy(dest,src,strlen(src)+1); printf("%s\n",dest); } void test_case2() { char dest[] = "memmove can be very userful..."; my_memcpy(dest+20,dest+8,3); printf("%s\n",dest); } int main() { test_case(); test_case2(); return 0; } |
【如何优化】
通常memcpy和memmove是按照字节byte拷贝,可以优化为按照机器字长word(32位机器4字节,64位机器8字节)进行拷贝。因为对一个word的操作cpu都可以在一个指令周期内完成,这样能够提高拷贝的效率。
【链接】
http://www.cnblogs.com/kekec/archive/2011/07/22/2114107.html
http://www.cplusplus.com/reference/cstring/memmove/
http://www.cplusplus.com/reference/cstring/memcpy/