0.两者比较:

  memmove用于从src拷贝count个字符到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中但复制后src内容会被更改但是当目标区域与源区域没有重叠则和memcpy函数功能相同

  memmove在copy两个有重叠区域的内存时可以保证copy的正确,而memcopy就不行了,但memcopy比memmove的速度要快一些,如:
char s[] = "1234567890";
char* p1 = s;
char* p2 = s+2;
  memcpy(p2, p1, 5)与memmove(p2, p1, 5)的结果就可能是不同的,memmove()可以将p1的头5个字符"12345"正确拷贝至p2,而memcpy()的结果就不一定正确了。

1.memcpy

首先是memcpy:

 #ifndef MEMCPY_H
#define MEMCPY_H #include <stdio.h> void *cat_memcpy(void *dst, const void *src, size_t n) {
if (NULL == dst || NULL == src)
return NULL; char *d = (char *)dst;
const char *s = (const char *)src; while (n--)
*d++ = *s++; return dst;
} #endif

2.memmove:

  memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。

  但当源内存和目标内存存在重叠时,memcpy会出现错误memmove能正确地实施拷贝,但这也增加了一点点开销。

memmove的处理措施:

(1)当源内存的首地址等于目标内存的首地址时,不进行任何拷贝

(2)当源内存的首地址大于目标内存的首地址时,实行正向拷贝

(3)当源内存的首地址小于目标内存的首地址时,实行反向拷贝

-- memmove实现

 #ifndef MEMMOVE_H
#define MEMMOVE_H /*********************************************************************
memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中 但当源内存和目标内存存在重叠时,memcpy会出现错误,
而memmove能正确地实施拷贝,但这也增加了一点点开销。 memmove的处理措施:
(1)当源内存的首地址等于目标内存的首地址时,不进行任何拷贝
(2)当源内存的首地址大于目标内存的首地址时,实行正向拷贝
(3)当源内存的首地址小于目标内存的首地址时,实行反向拷贝 内存的5种情况:
(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
*********************************************************************/ #include <stdio.h> void *cat_memmove(void *dst, const void *src, size_t n) {
if (NULL == dst || NULL == src || == n)
return NULL; char *d = (char *)dst;
const char *s = (const char *)src; if (s > d) { // (2)当源内存的首地址大于目标内存的首地址时,实行正向拷贝
while (n--)
*d++ = *s++;
} else if (s < d){ // (3)当源内存的首地址小于目标内存的首地址时,实行反向拷贝
d = d + n - ; // move to end
s = s + n - ; // move to end
while (n--)
*d-- = *s--;
}
// (1)当源内存的首地址等于目标内存的首地址时,不进行任何拷贝
// do nothing return dst;
} #endif

src和dst的内存示意图,5种情况(自己在纸上画画就很容易明白的!):

(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

可以看到(1)、(2)处理方法一样;(4)、(5)处理方法一样。

main:测试代码:

 #include "memcpy.h"
#include "memmove.h" void test_memcpy();
void test_memmove(); int main() { test_memmove(); return ;
} void test_memcpy() {
char dst[] = {};
char *src = "test memcpy";
char *ret = (char *)cat_memcpy(dst, src, strlen(src) + );
char *ret1 = (char *)cat_memcpy(dst, src, strlen(src));
printf("%s\n%s\n%s\n", ret, dst, ret1);
} void test_memmove() {
char dst[] = { };
char *src = "test cat_memmove";
char *ret = (char *)cat_memmove(dst, src, strlen(src) + );
char *ret1 = (char *)cat_memmove(dst, src, strlen(src));
printf("%s\n%s\n%s\n", ret, dst, ret1); printf("\n====================================\n[src<dst]:\n");
char s[] = "";
char* p1 = s;
char* p2 = s + ;
char *sRet = (char *)cat_memmove(p2, p1, );
printf("memmove:\n%s\n%s\n%s\n\n", sRet, p1, p2); char s1[] = "";
char* p11 = s1;
char* p22 = s1 + ;
char *sRet1 = (char *)cat_memcpy(p22, p11, );
printf("memcpy:\n%s\n%s\n%s\n", sRet1, p11, p22); printf("\n====================================\n[src>dst]:\n");
char ss[] = "";
char* pp1 = ss;
char* pp2 = ss + ;
char *ssRet = (char *)cat_memmove(pp1, pp2, );
printf("memmove:\n%s\n%s\n%s\n\n", ssRet, pp1, pp2); char ss1[] = "";
char* pp11 = ss1;
char* pp22 = ss1 + ;
char *ssRet1 = (char *)cat_memcpy(pp11, pp22, );
printf("memcpy:\n%s\n%s\n%s\n", ssRet1, pp11, pp22);
}

ref:

http://www.cnblogs.com/kekec/archive/2011/07/22/2114107.html

http://blog.chinaunix.net/uid-22780578-id-3346391.html

C语言实现memcpy和memmove的更多相关文章

  1. memcpy与memmove的区别

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

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

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

  3. C语言标准库函数memcpy和memmove的区别以及内存重叠问题处理

    ①memcpy()和memmove()都是C语言中的标准库函数,定义在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下: void *memcpy(void *dst, cons ...

  4. 【VS开发】【C/C++开发】memcpy和memmove的区别

    memcpy和memmove()都是C语言中的库函数,在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下: void *memcpy(void *dst, const void ...

  5. memcpy vs memmove

    [本文连接] http://www.cnblogs.com/hellogiser/p/memcpy_vs_memmove.html [分析] memcpy与memmove的目的都是将N个字节的源内存地 ...

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

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

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

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

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

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

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

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

随机推荐

  1. SQL Server ->> GROUPING SETS, CUBE, ROLLUP, GROUPING, GROUPING_ID

    在我们制作报表的时候常常需要分组聚合.多组聚合和总合.如果通过另外的T-SQL语句来聚合难免性能太差.如果通过报表工具的聚合功能虽说比使用额外的T-SQL语句性能上要好很多,不过不够干脆,还是需要先生 ...

  2. SQL SERVER ->> Data Compression

    最近做了一个关于数据压缩的项目,要把整个SQL SERVER服务器下所有的表对象要改成页压缩.于是趁此机会了解了一下SQL SERVER下压缩技术. 这篇文章几乎就是完全指导手册了 https://t ...

  3. 【算法题】- 求和等于K子数组

    一整数(有正有负)数组,用尽量少的时间计算数组中和为某个整数的所有子数组 public class SumK { public static void main(String[] args) { in ...

  4. USACO Section 2.2: Runaround Numbers

    简单题 /* ID: yingzho1 LANG: C++ TASK: runround */ #include <iostream> #include <fstream> # ...

  5. 如何修改linux时间? 校正linux系统的时间

    第一步:通过xshell远程连接到linux系统 第二步:输入 tzselect 第三步:选择所在的州,中国人请选择 5 ,亚洲 第四步:选择你所在的国家,中国人请选择9,中国 第五步:选择一个时区, ...

  6. Gumshoe - Microsoft Code Coverage Test Toolset

    Gumshoe - Microsoft Code Coverage Test Toolset 2014-07-17 What is Gumshoe? How to instrument a binar ...

  7. @Inject.@Resource.@Autowired 的区别

    @Inject:Struts2的注解, @Resource : J2EE提供,用于注入,( j2ee提供的 ) 默认按名称装配,@Resource(name="beanName") ...

  8. R语言实现数据集某一列的频数统计——with和table

    with(priority.train, table(From.EMail)) 统计priority.train中From.EMail的频数

  9. 听说noip2015有幻方

    终于可以说一句:pascal大法好了 magic.pp是写好的算幻方哦…… 虽然这种水题大家都会,也没什么卵用……

  10. asp.net限时发送手机验证码

    html代码 <p> <strong>手机验证码:</strong> <asp:TextBox ID="code" runat=" ...