一、memcpy和memmove函数的用途
memcpy
和memmove
函数都是用来对内存进行操作的,两函数原型如下:
void *memcpy( void *dest, const void *src, size_t count );
void *memmove( void *dest, const void *src, size_t count );
这两个函数除了函数名不同之外,其他地方一模一样,其实其功能从某种意义上来说也是一样的,都是为了将内存从src
开始的count
个字节的数据拷贝到从dest
开始的count
个字节空间内。但是既然是两个函数,那肯定有其不同之处,memcpy
函数要求操作的空间不能有重叠,但是memmove
函数可以。
二、实现原理
memcpy
和memmove
函数在实现原理方面相似,但是memcpy
对有重叠空间的拷贝不能保证正确,也就是上面说的操作空间不能有重叠,虽然在使用上发现尽管有重叠依然是正确的,但是按照系统给出的说明,我们可以对两函数模拟实现。
1、memcpy,对有重复空间不做特殊处理
void* my_memcpy(void* dst, const void* src, size_t count)
{
assert(dst != NULL && src != NULL);
void* p = dst;
while (count > 0)
{
*(char*)p = *(char*)src;
((char*)p)++;
((char*)src)++;
count--;
}
return dst;
}
2、memmove,在memcpy的基础上判断其重叠是否会对结果造成影响,如果会,就反向拷贝
void* my_memmove(void* dst, const void* src, size_t count)
{
assert(dst != NULL && src != NULL);
void* p = dst;
//如果copy而不被覆盖,就直接copy
if (dst < src || (char*)dst >= (char*)src + count)
{
while (count > 0)
{
*(char*)p = *(char*)src;
((char*)p)++;
((char*)src)++;
count--;
}
}
//改变方向,从后往前拷贝
else
{
(char*)src += count - 1;
(char*)p += count - 1;
while (count > 0)
{
*(char*)p = *(char*)src;
((char*)p)--;
((char*)src)--;
count--;
}
}
return dst;
}
对于memmove中什么情况下回影响结果以及为什么反向拷贝就会避免这种情况,可以画一画图进行理解。