实现标准c语言的memcpy接口,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

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)内存低端 内存高端 start at end of s

(2)内存低端 --d-----> 内存高端 start at end of s

(3)内存低端 内存高端 do nothing

(4)内存低端 --s-----> 内存高端 start at beginning of s

(5)内存低端 内存高端 start at beginning of s

*********************************************************************/

#include

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)内存低端 内存高端 start at end of s

(2)内存低端 --d----->      内存高端 start at end of s

(3)内存低端              内存高端 do nothing

(4)内存低端 --s----->      内存高端 start at beginning of s

(5)内存低端 内存高端 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

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:

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

关于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() ---------------------- ...

随机推荐

c# WebClient文件下载

public void HttpDownload(string url, string path, ResourceType type) { using (var client = new WebCl ...

android studio增量更新

一.概述 1.1 概念 增量更新即是通过比较 本机安装版本 和 想要安装版本 间的差异,产生一个差异安装包,不需要从官网下载并安装全量安装包,更不需要将本机已安装的版本下载,而仅仅只是安装此差异安装包 ...

sed初学

1.连接多个sed命令,使用;号 2.批量修改文本中匹配到相应字符串的行 例如,将文本中log_server_port = "12345" 的12345修改成变量中存储的值 sed ...

Java基础知识强化之集合框架笔记16:List集合的特有功能概述和测试

1. List集合的特有功能概述: (1)添加功能: void add(int index, Object element):在指定位置添加元素 (2)获取功能: Object get(int ind ...

cf B. Sereja and Suffixes

http://codeforces.com/contest/368/problem/B 从后往前找一遍就可以. #include #include

蓝桥杯比赛java 练习《立方变自身》

立方变自身 观察下面的现象,某个数字的立方,按位累加仍然等于自身.1^3 = 1 8^3  = 512    5+1+2=817^3 = 4913   4+9+1+3=17... 请你计算包括1,8, ...

【BZOJ1036】【ZJOI2008】数的统计

接着找树剖的题...传送门(点我) 题意:给你一棵无根树,有三种操作:查询树上2点路径的点权和/最大点权:更改某点的点权. 解题思路:树链剖分裸题,我采用了常数较小的zkw线段树维护剖下来的树(毕竟线 ...

python编码问题分析

本文首先简要介绍编码转换的基本原理,然后针对字符串处理.文件读写的两个实例,具体分析编码问题的处理方式. 1.编码转换的基本原理 我们知道,只有在面对中文.日文等编码字符(以下均以中文字符为例)时,才 ...

coderfun-boot接私活利器,文档详实,非一般的开发速度

项目主页:https://gitee.com/klguang/coderfun-boot 演示地址:http://106.15.195.9:8080/admin/项目文档:https://www.ka ...

table size script :

I think Jonathan Lewis has explained the algorithm before, but it's alsosomething that we have inves ...

你可能感兴趣的