一、函数声明
memcpy
void * memcpy ( void * destination,const void * source,size_t num );
·函数memcpy从source的位置开始向后复制num个字节的数据到destination的内存位置。
·这个函数在遇到’\0’的时候并不会停下来。
·如果source和destination有任何的重叠,复制的结果都是未定义的。
memmove
void * memmove ( void * destination,const void * source,size_t num );
和memcpy的差别就是memmove函数处理的源内存块和目标内存块是可以重叠的。
·如果源空间和目标空间出现重叠,就得使用memmove函数处理。
二、区别与联系
相同点:
两个都是内存拷贝,对所有类型都适用;
不同点:
(1) memcpy()函数是从前往后拷贝;假入出现内存重叠的现象;拷贝结果可能出错;
(2) memmove()函数在memcpy()函数的基础上加入了对内存重叠拷贝的处理;引入了倒序拷贝的方式处理内存重叠的某些情况;保证拷贝的正确性;
综上:在现实中使用memmove()函数会比较好一点;
三、情况分析
分析出下图6种情况:
不难发现,只有第二种情况由于拷贝dest前两个字节时覆盖了src原来的内容,所以接下来的拷贝会出现错误,产生重叠。因此我们只需要在第二种情况下进行拷贝时会从src的最后向前拷贝N个字节,避免了覆盖原来内容的过程。
四、 源程序
memcpy:
void * my_memcpy(void * dest, const void * src, size_t num)
{
assert(dest != NULL && src != NULL);
char *pdest = (char*)dest;
const char *psrc = (const char*)src;
while (num-- > 0)
{
*pdest++ = *psrc++;
}
return dest;
}
memmove:
void * my_memmove(void * dest, const void * src, size_t num)
{
assert(dest != NULL && src != NULL);
char *pdest = (char*)dest;
const char *psrc = (const char*)src;
if (psrc >= pdest || pdest >= psrc + num)
{
while (num-- > 0)
{
*pdest++ = *psrc++;
}
}
else
{
psrc = psrc + num - 1;
pdest = pdest + num - 1;
while (num-- > 0)
{
*pdest-- = *psrc--;
}
}
return dest;
}
五、总代码及运行结果:
memcpy:
#include<stdio.h>
#include<assert.h>
void * my_memcpy(void * dest, const void * src, size_t num)
{
assert(dest != NULL && src != NULL);
char *pdest = (char*)dest;
const char *psrc = (const char*)src;
while (num-- > 0)
{
*pdest++ = *psrc++;
}
return dest;
}
int main()
{
char str[20] = "ghfjkhkj";
printf("str = %s\n", str);
my_memcpy(str, str + 3, 4);
printf("str = %s\n", str);
}
memmove:
#include<stdio.h>
#include<assert.h>
void * my_memmove(void * dest, const void * src, size_t num)
{
assert(dest != NULL && src != NULL);
char *pdest = (char*)dest;
const char *psrc = (const char*)src;
if (psrc >= pdest || pdest >= psrc + num)
{
while (num-- > 0)
{
*pdest++ = *psrc++;
}
}
else
{
psrc = psrc + num - 1;
pdest = pdest + num - 1;
while (num-- > 0)
{
*pdest-- = *psrc--;
}
}
return dest;
}
int main()
{
char str[20] = "qyuwhsjagf";
printf("str = %s\n", str);
my_memmove(str+3, str , 4);
printf("str = %s\n", str);
}