memcpy和memmove最大的区别就是,memcpy会出现内存覆盖,而memmove不会
废话不多说直接上代码
#include<iostream>
#include<assert.h>
using namespace std;
void *my_memcpy(void* dest, const void* src, size_t count)//不考虑内存重叠,若考虑,则同下memmove
{
assert(dest != NULL&&src != NULL);
char* pdest =(char*) dest;
const char* psrc =(const char*) src;
while (count--)
*pdest++ = *psrc++;
return dest;
}
void* my_memmove(void* dest, void* src, size_t count)//同考虑内存重叠的memcpy
{
assert(dest != NULL && src != NULL);
char* pdest = (char*)dest;
const char* psrc = (char*)src;
if(psrc >= pdest || pdest >= (psrc + count))//当源内存地址在目的内存地址之后或者目的地址在源内存地址+count之后,可以正常拷贝
{
while (count--)
{
*pdest++ = *psrc++;
}
}
else //否则需要从后往前拷贝,防止出现覆盖
{
while (count--)
{
*(pdest + count) = *(psrc + count);
}
}
return dest;
}
这是我自己实现这两个函数的代码。
主函数:
void main()
{
char a[]="abcdefg";
char *b=a+2;
cout<<b<<endl;
my_memcpy(b,a,5);
cout<<b<<endl;
}
在这里主函数本该输出的是cdefg和abcde,但是编译器输出如下:
再看调用库函数的memcpy:
void main()
{
char a[]="abcdefg";
char *b=a+2;
cout<<b<<endl;
memcpy(b,a,5);
cout<<b<<endl;
}
这里并不是我的my_memcpy写的有问题,而是编译器优化了系统的memcpy,这里只是为了区分memcpy和memmove,所以选择调用自己的my_memcpy,在此解释。
下面说一下为什么出现了内存重叠:
a b c d e f g 这是a字符串,即Src
c d e f g 这是b字符串,即Dest
首先拷贝上面的a到下面c的位置,然后b到d的位置,但内存中c的位置已经变成了a,所以又拷贝a到e的位置,内存中的d变成了b,所以又拷贝b到f的位置,以此类推,输出结果为ababa,这就是所说的内存重叠
具体可参考:点击打开链接
在面试的时候,基本会让写考虑内存重叠的my_memcpy,其实就是上面的my_memove,实现方式是判断是否会出现内存重叠的情况,如果会出现那么就从后往前拷贝,防止这种情况的出现。