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() ---------------------- ...
随机推荐
- SSIS ->> Error Handling
Event Handler Each task and container raises events as it runs, such as an OnError event, among seve ...
- Friends(老友记)(六人行)相关资源
迅雷账号:104303980 老友记 Friends 的所有种子: http://www.ttmeiju.com/meiju/Friends.html 老友记(friends)高清(720p)+字幕 ...
- 基于webpivottable做的透视表
1.绑定数据和配置: var wptConfig=<%= wptConfig%>; webPivotTable.setCsvData(<%=dataFields %>, < ...
- Javascript performance
I just went through some vedio related to javascript performance which is great, Here is the notes I ...
- Android应用开发学习笔记之菜单
作者:刘昊昱 博客:http://blog.csdn.net/liuhaoyutz Android中的菜单分为选项菜单(OptionMenu)和上下文菜单(Context Menu).通常使用菜单资源 ...
- Android之网络请求库
自己学习android也有一段时间了,在实际开发中,频繁的接触网络请求,而网络请求的方式很多,最常见的那么几个也就那么几个.本篇文章对常见的网络请求库进行一个总结. HttpUrlConnection ...
- Oracle —— 函数 length() 和 lengthb() 的区别
先看看几个例子: select length('Oracle') from dual 结果:6 select lengthb('Oracle') from dual 结果:6 select lengt ...
- 1.Cadence16.5的安装教程[原创]
http://jingyan.baidu.com/article/6d704a1319107a28db51cac9.html
- leetcode:Excel Sheet Column Number
Given a column title as appear in an Excel sheet, return its corresponding column number. For exampl ...
- 【转】Android Gson的使用
Android Gson 2014 年 05 月 22 日 android 目前的客户端大都有和服务端进行交互,而数据的格式基本就是json了,于是在Android开发中就经常用到json解析,方便的 ...