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. Database File Management ->> Shrink Data File

    今天在开发环境遇到了一个问题,我们发现服务器上的硬盘空间满了,查看了下发现这个盘存放的数据库文件应该是来源一个并非很大的库才对.检查之后发现这个数据库下的某个数据文件占了盘符下70%的空间,而大部分数 ...

  2. 神经网络:卷积神经网络CNN

    一.前言 这篇卷积神经网络是前面介绍的多层神经网络的进一步深入,它将深度学习的思想引入到了神经网络当中,通过卷积运算来由浅入深的提取图像的不同层次的特征,而利用神经网络的训练过程让整个网络自动调节卷积 ...

  3. 卷积神经网络CNN全面解析

    卷积神经网络(CNN)概述 从多层感知器(MLP)说起 感知器 多层感知器 输入层-隐层 隐层-输出层 Back Propagation 存在的问题 从MLP到CNN CNN的前世今生 CNN的预测过 ...

  4. hdu4185解题报告

    这里我居然能自己想想到怎么建图匹配,很是不容易... 题意:这里有一片油田,但是不是纯净的,有的地方是水,现在有一个捞石油的机器,但是这个机器捞的范围是固定的,是2*1的一个矩形大小,那么对于整个油田 ...

  5. 【Cocosd2d实例教程二】地图编辑器Tiled的安装使用

    (转载请注明出处:http://blog.csdn.net/buptgshengod) 我们知道cocos2d是一个基于2d效果的游戏引擎,那么如果制作一个2d手机游戏我们需要创建相应的游戏画面,而c ...

  6. 深入理解Java内存模型(五)——锁

    锁的释放-获取建立的happens before 关系 锁是java并发编程中最重要的同步机制.锁除了让临界区互斥执行外,还可以让释放锁的线程向获取同一个锁的线程发送消息. 下面是锁释放-获取的示例代 ...

  7. itnesse实现api接口自动化测试学习

    上午在园子里乱逛,看了不少小伙伴们分享的接口测试方面的知识,大家所叙述到的一些经验或多或少,我也曾遇到过,突然意识到知识的点滴积累是多么的重要,我记得我最早接触接口测试的时候,就是只在浏览器里人工测试 ...

  8. HDU 4726 Kia's Calculation(贪心构造)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4726 题意:给出两个n位的数字,均无前缀0.重新排列两个数字中的各个数,重新排列后也无前缀0.得到的两 ...

  9. Python 数据类型转换

    Python提供的基本数据类型主要有:布尔类型.整型.浮点型.字符串.列表.元组.集合.字典.日期等等 函数                      描述     type(x)  x的数据类型   ...

  10. c#换ip代理源码

    很多朋友都想如何提高自己的网站流量,可是都没有什么好的办法 经过很长时间的研究,在C#中实现了,当然了,这部分代码其中一部分是网上的,不是原创. using System; using System. ...