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;
my_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,这就是所说的内存重叠
具体可参考:https://blog.csdn.net/li_ning_/article/details/51418400
在面试的时候,基本会让写考虑内存重叠的my_memcpy,其实就是上面的my_memove,实现方式是判断是否会出现内存重叠的情况,如果会出现那么就从后往前拷贝,防止这种情况的出现。