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() ---------------------- ...
随机推荐
- chrome开发配置(四)生成项目及配置库引用
1.运行gclient runhooks --force .会重新下载个python 2.7版本的,并且下载好几个文件,大概1个多小时:
- chrome开发配置(二)获取源代码
1.下载源代码,这里使用最简单的下载,chrome打包好的共享在百度云盘,点击下载 2.建议下载7z压缩工具解压压缩包,大概1个多小时. 3.至于以后怎么更新到最新版不能,等编译生成成功了,我们再具体 ...
- SSIS ->> Script Debugging and Troubleshooting
Breakpoint是调试过程中最重要的手段,不仅对于Script Task和Script Component,对于任何其他的组件也是如此.可以在某个Event(如OnError)触发的时候设置断点来 ...
- c# 将字符串转换为逻辑表达式(字符串转换布尔)
比如:string str="6>5"; 要的效果是:bool result=6>5 方案一: 命名空间:System.Data: DataTable dt = new ...
- ArcGIS Engine中的8种数据访问
数据是GIS的基础, 访问数据也是进行任何复杂的空间分析及空间可视化表达的前提.ArcGIS支持的数据格式比较丰富,对不同的数据格式支持的程度也有很大差异.本文主要介绍一下以下八种数据格式在ArcGI ...
- 32-语言入门-32-Triangular Sums
题目地址: http://acm.nyist.net/JudgeOnline/problem.php?pid=122 描述The nth Triangular number, T(n) = 1 ...
- [JWFD开源工作流]JWFD开源工作流官方下载内容更新
在更新版的JWFD二次开发包中,我正在实现单线程的时钟控制器,动了下引擎的源代码,这个更新包主要是升级界面,内核代码,大家就不用升级了.. 代码提示: 请修改代码包中(org.jwfd.workflo ...
- 源码解析Android中View的measure量算过程
Android中的Veiw从内存中到呈现在UI界面上需要依次经历三个阶段:量算 -> 布局 -> 绘图,关于View的量算.布局.绘图的总体机制可参见博文< Android中View ...
- Linux同步机制 - 基本概念(死锁,活锁,饿死,优先级反转,护航现象)
死锁(deadlock) 是指两个或两个以上的进程在执行过程中,因争夺资源而造成的一种互相等待的现象,若无外力作用,它们都将无法推进下去.此时称系统处于死锁状态或系统产生了死锁,这些永远在互相等待的进 ...
- jquery ajax的async属性的理解
$(function(){ queryTemplateSort(); // fillAddTemplatePage(); function queryTemplateSort() { $.ajax({ ...