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/