C语言实现memcpy和memmove
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的更多相关文章
- memcpy与memmove的区别
在面试中经常会被问道memcpy与memove有什么区别? 整理如下: 其实主要在考C的关键字:restrict C库中有两个函数可以从一个位置把字节复制到另一个位置.在C99标准下,它们的原型如下: ...
- memcpy、memmove、memset、memchr、memcmp、strstr详解
第一部分 综述 memcpy.memmove.memset.memchr.memcmp都是C语言中的库函数,在头文件string.h中.memcpy和memmove的作用是拷贝一定长度的内存的内容,m ...
- C语言标准库函数memcpy和memmove的区别以及内存重叠问题处理
①memcpy()和memmove()都是C语言中的标准库函数,定义在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下: void *memcpy(void *dst, cons ...
- 【VS开发】【C/C++开发】memcpy和memmove的区别
memcpy和memmove()都是C语言中的库函数,在头文件string.h中,作用是拷贝一定长度的内存的内容,原型分别如下: void *memcpy(void *dst, const void ...
- memcpy vs memmove
[本文连接] http://www.cnblogs.com/hellogiser/p/memcpy_vs_memmove.html [分析] memcpy与memmove的目的都是将N个字节的源内存地 ...
- memcpy、memmove、memset及strcpy函数实现和理解
memcpy.memmove.memset及strcpy函数实现和理解 关于memcpy memcpy是C和C++ 中的内存拷贝函数,在C中所需的头文件是#include<string.h> ...
- 关于memcpy和memmove的一点说明
今天看到书上降到memcpy和memmove的区别才突然发现原来两者之间有如此区别,以前只知道这两个函数是 实现同样的功能,没有接触到其不同. memcpy和memmove在MSDN的定义如下: 从两 ...
- strcpy()、memcpy()、memmove()、memset()的内部实现
一直想知道 strcpy().memcpy().memmove().memset()的内部实现 strcpy(), 字符串拷贝. char *strcpy(char *strDest, const c ...
- 第 16 章 C 预处理器和 C 库(string.h 库中的 memcpy() 和 memmove())
/*----------------------------------------- mems.c -- 使用 memcpy() 和 memmove() ---------------------- ...
随机推荐
- Android BroadcastReceiver实时监听电量
Android系统中实时的监听手机电量以及开机启动功能都是通过BroadcastReceiver组件实现的.我们可以动态注册这个类的一个实例通过 Context.registerReceiver()方 ...
- iScrolljs 模拟android相册
var showBigImage = new iScroll('showBigImage', { snap: 'div', snapThreshold: 480, momentum: false, z ...
- PHP代码优化技巧大盘点
PHP优化的目的是花最少的代价换来最快的运行速度与最容易维护的代码.本文给大家提供全面的优化技巧. 1.echo比print快. 2.使用echo的多重参数代替字符串连接. 3.在执行for循环之前确 ...
- 在linux系统下检查postgresql数据库安装,登录数据库及简单的查看数据库
1. 检查Linux系统是否安装数据库 首先查看自己的系统是否安装了postgresql数据库命令如下: rpm -qa | grep postgresql 如果没有显示查询结果(如下图所示)说 ...
- [51NOD1127]最短的包含字符串(尺取法)
题目链接:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1127 思路:尺取法,一开始我考虑更新右指针,直到遇到一个和l指 ...
- Android高手进阶教程(二十八)之---Android ViewPager控件的使用(基于ViewPager的横向相册)!!!
分类: Android高手进阶 Android基础教程 2012-09-14 18:10 29759人阅读 评论(35) 收藏 举报 android相册layoutobjectclassloade ...
- xxx_cast类型转换
xxx_cast是一个统称,它指的是static_cast(静态转换),const_cast(常量转换),reinterpert_cast(重解释转换),dynamic_cast(动态转换).本次我们 ...
- matlab中,在灰度解剖图上叠加阈值图,by by DR. Rajeev Raizada
1.参考 reference 1. tutorial主页:http://www.bcs.rochester.edu/people/raizada/fmri-matlab.htm. 2.speech_b ...
- phpcms二级菜单
二级 {pc:content action="category" catid="0" siteid="$siteid" order=&quo ...
- Java中传值与传引用
不管Java参数类型是什么,一律传递参数的副本. <Thinking In Java>:“When you're passing primitives into a method,you ...