1. 问题引入
内存覆盖情况1(会改变src内存的值,如再操作src,将会有出错的风险):
内存覆盖情况2(拷贝最后两个字节时,src中的内存已经发生改变):
2. memcpy
2.1 原型
void *memcpy(void *dest, const void *src, size_t n);
描述:memcpy()函数从src内存中拷贝n个字节到dest内存区域,但是源和目的的内存区域不能重叠。
返回值说明:返回指向dest的void *指针
2.2 实现
void* MyMemcpy(void* dst, const void* src, size_t n)
{
char *tmp = (char*)dst;
char *s_src = (char*)src;
while(n--) {
*tmp++ = *s_src++;
}
return dst;
}
这种方式会导致如上图中内存覆盖情况2中所示,当拷贝最后两个字节的时候src中的内容已经改变。
3. memmove
3.1 原型
void *memmove(void *dest, const void *src, size_t n);
描述:memmove用于从source拷贝count个字符到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中(此时源字符串尾部字符改变)。
返回值说明:返回指向dest的void *指针
3.2 实现
void* MyMemmove(void* dst, void* src, size_t n)
{
if((nullptr == dst) || (nullptr == src))
{
return nullptr;
}
void* tmp= dst;
if (dst <= src || dst>= (src + n)) //此时无需考虑内存重叠
{
while (n--)
*dst++ = *src++;
}
else
{
dst+= n- 1;
src+= n- 1;
while (n--)
*dst-- = *src--; //倒序拷贝
}
return tmp;
}
4. 扩展
1)memcpy的效率比memmove略高;
2)字符串拷贝函数strcpy同样存在内存重叠的问题;