您的位置:首页 > 编程语言 > C语言/C++

【C语言】memcpy函数和memmove函数的实现与区别

2015-04-16 23:46 405 查看
memcpy与memmove的目的都是将N个字节的源内存地址的内容拷贝到目标内存地址中。

我们先实现memcpy的功能:

#include <stdio.h>
#include <assert.h>
void *my_memcpy(void *dst,const void *src,int n)
{
void *ret = dst;
char *p1 = (char*)dst;
char *p2 = (char*)src;
assert(dst);
assert(src);
while(n--)
{// 注意,memcpy函数没有处理dst和src区域是否重叠的问题
*p1++ = *p2++;
}
*p1 = '\0';
return ret;
}

int main ()
{
char p[] = "bit-tech";
char q[10];
my_memcpy(q,p,4);
printf("%s\n",q);
return 0;
}


函数原型中的形参设置为void *型是为了使用户每次传入不同类型的实参时,函数都能接收。但如果需要对形参进行运算,那么必须对形参进行强制类型转换。



那么我们接着来看一下memmove函数的实现:

memmove的处理措施:

(1)当源内存的首地址等于目标内存的首地址时,不进行任何拷贝

(2)当源内存的首地址大于目标内存的首地址时,实行正向拷贝

(3)当源内存的首地址小于目标内存的首地址时,实行反向拷贝

#include <stdio.h>
#include <assert.h>
void *my_memmove(void *dst,const void *src,int n)
{
void *ret = dst;
char *p1 = (char*)dst;
char *p2 = (char*)src;
assert(dst);
assert(src);
if((p2 <= p1) && (p1 <= p2+n))
{ // 若dst和src区域交叉,则从尾部开始向起始位置拷贝,这样可以避免数据冲突
p2 = p2+n-1;
p1 = p1+n-1;
while(n--)
{
*p1 = *p2;
p1--;
p2--;
}
}
else
{ // 若dst和src区域没有重叠,则从起始处开始逐一拷贝
while(n--)
{
*p1 = *p2;
p1++;
p2++;
}
*p1 = '\0';
}
return ret;
}
int main ()
{
char p[] = "bit-tech";
char q[10];
my_memmove(p+1,p,6);
printf("%s\n",p);
my_memmove(q,p,6);
printf("%s\n",q);
return 0;
}




总之,两者的区别在于:

当源内存和目标内存存在重叠时,memcpy会出现错误,而memmove能正确地实施拷贝,但这也增加了一点点开销。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: