memmove源码
memmove
函数原型:void *memmove(void *dest, const void *src, size_t count)
返回值说明:返回值为void *
参数说明:dest,src分别为目标串和源串的首地址。count为要移动的字符的个数
函数说明:memmove用于从src拷贝count个字符到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中(此时源字符串尾部字符改变)
void* My_memmove(void* dest, const void* src, size_t num)
{
assert(dest && src);
void* ret = dest;
if (dest < src)
{
while (num--)//前->后
{
*(char*)dest = *(char*)src;
dest = (char*)dest + 1;
src = (char*)src + 1;
}
}
else
{
while (num--)//后->前
{
*((char*)dest + num) = *((char*)src + num);
}
}
return ret;
}
memcpy源码
memcpy
函数原型:void *memcpy(void *dest, const void *src, size_t count);
返回值说明:返回指向dest的void *指针函数说明:memcpy功能和memmove相同,但是memcpy中dest和src中的区域不能重叠,否则会出现未知结果。
void* memcpy(void* dst, const void* src, size_t len)
{
if (NULL == dst || NULL == src) {
return NULL;
}
void* ret = dst;
if (dst <= src || (char*)dst >= (char*)src + len) {
//没有内存重叠,从低地址开始复制
while (len--) {
*(char*)dst = *(char*)src;
dst = (char*)dst + 1;
src = (char*)src + 1;
}
}
else {
//有内存重叠,从高地址开始复制
src = (char*)src + len - 1;
dst = (char*)dst + len - 1;
while (len--) {
*(char*)dst = *(char*)src;
dst = (char*)dst - 1;
src = (char*)src - 1;
}
}
return ret;
}
内存重叠
两个函数的区别
函数memcpy() 从src 指向的区域向dest指向的区域复制count个字符,如果两数组重叠,不定义该函数的行为。而memmove(),如果两函数重叠,赋值仍正确进行。memcpy函数假设要复制的内存区域不存在重叠,如果你能确保你进行复制操作的的内存区域没有任何重叠,可以直接用memcpy;如果你不能保证是否有重叠,为了确保复制的正确性,你必须用memmove。memcpy的效率会比memmove高一些.
顺便记录一下C中的内存划分
内存重叠的情况
memmove不需要考虑内存重叠
memcpy需要考虑内存重叠
解决方式:
(1)当源内存的首地址大于目标内存的首地址时,实行正向拷贝;
(2)当源内存的首地址小于目标内存的首地址时,实行反向拷贝 。
就记录到这里吧!!