【本文连接】

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-;
        s = s+count-;
        while(count--)
        {
            *d-- = *s--;
        }
    }
    else 
    {
        // do nothing
    }
    return dest;
}

void test_case()
{
    char dest[];
    const char *src = "hello";
    my_memcpy(dest,src,strlen(src)+);
    printf("%s\n",dest);
}

void test_case2()
{
    char dest[] = "memmove can be very userful...";
    my_memcpy(dest+,dest+,);
    printf("%s\n",dest);
}

int main()
{
    test_case();
    test_case2();
    return ;
}

【如何优化】

通常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/

memcpy vs memmove的更多相关文章

  1. memcpy与memmove的区别

    在面试中经常会被问道memcpy与memove有什么区别? 整理如下: 其实主要在考C的关键字:restrict C库中有两个函数可以从一个位置把字节复制到另一个位置.在C99标准下,它们的原型如下: ...

  2. C语言实现memcpy和memmove

    0.两者比较: memmove用于从src拷贝count个字符到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中.但复制后src内容会被 ...

  3. memcpy、memmove、memset及strcpy函数实现和理解

    memcpy.memmove.memset及strcpy函数实现和理解 关于memcpy memcpy是C和C++ 中的内存拷贝函数,在C中所需的头文件是#include<string.h> ...

  4. 关于memcpy和memmove的一点说明

    今天看到书上降到memcpy和memmove的区别才突然发现原来两者之间有如此区别,以前只知道这两个函数是 实现同样的功能,没有接触到其不同. memcpy和memmove在MSDN的定义如下: 从两 ...

  5. strcpy()、memcpy()、memmove()、memset()的内部实现

    一直想知道 strcpy().memcpy().memmove().memset()的内部实现 strcpy(), 字符串拷贝. char *strcpy(char *strDest, const c ...

  6. 第 16 章 C 预处理器和 C 库(string.h 库中的 memcpy() 和 memmove())

    /*----------------------------------------- mems.c -- 使用 memcpy() 和 memmove() ---------------------- ...

  7. 模拟实现memcpy 与 memmove

    模拟实现memcpy 与 memmove 1.str系列的函数只能处理字符串——>必须带有'\0'2.memcpy内存处理函数:不涉及'\0',需要包含头文件 string.h3.source的 ...

  8. memcpy、memmove、memset、memchr、memcmp、strstr详解

    第一部分 综述 memcpy.memmove.memset.memchr.memcmp都是C语言中的库函数,在头文件string.h中.memcpy和memmove的作用是拷贝一定长度的内存的内容,m ...

  9. C/C++之Memcpy and memmove

    memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中. 但当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开 ...

随机推荐

  1. jQuery 元素的选中, 置顶、上移、下移、置底、删除

    如截图: <ul> <li class="li01" onclick="C_columnSetTop(this)"><i>& ...

  2. MongoDB创建数据库和集合命令db.createCollection详解(转)

    切换/创建数据库 use yourDB;  当创建一个集合(table)的时候会自动创建当前数据库 完整的命令如下:db.createCollection(name, {capped: <Boo ...

  3. 使用自己的ClassLoader实现热替换

    首先实现一个自己的ClassLoader,该ClassLoader重写findClass方法. 从classpath中加载类资源. 注意,不要重写loadClass方法.  因为在使用自定义的MyCl ...

  4. Netbeans 设置模板

    /** * @Description * @author ${user} * @date ${date} ${time} * @copyright ${copyright} */ 工具-->模板 ...

  5. Teradata SQL programming

    Teradata的SQL设计和Oracle真不是一个水平, 一点美感的没有.  上个世纪它靠着MPP一招鲜吃变天, 居然做了十多年数据仓库的老大,  时过境迁, 现在有不少SQL On Hadoop ...

  6. ios修改textField的placeholder的字体颜色和大小

    textField.placeholder = @"username is in here!"; [textField setValue:[UIColor redColor] fo ...

  7. 新年新技术:HTTP/2

    新的一年,项目也要带着发展的眼光往前走,得跟上潮流,当然前提是自己真的用的上. 用的上用不上都得先简单了解下. 2月下旬Google发布了首个基于HTTP/2的RPC框架GRPC,它是基于HTTP/2 ...

  8. PHP 文件与目录操作函数总结

    >>>文件操作 打开 fopen();    打开文件 读取内容 fread();    从文件指针 handle 读取最多 length 个字节 readfile();    读入 ...

  9. Codeforces Round #270 1003

    Codeforces Round #270 1003 C. Design Tutorial: Make It Nondeterministic time limit per test 2 second ...

  10. CSS样式案例(2)-制作一个简单的登录界面

    首先来张完工的效果图. 一.html文件如下: <!DOCTYPE html> <html> <head> <meta charset="UTF-8 ...