1.memmove要解决的问题
strcpy只能拷贝字符串,为了解决这一问题,则有了memcpy这一函数。但是针对重叠内存的拷贝,memcpy最初并不能解决这一问题(后期优化过的memcpy能够实现重复内存的拷贝),为此出现了memmove.
2.何为重叠内存
比如说,现在要将 4 5 6 7 8copy到 1 2 3 4 5的位置上去,即源的头和目标位置的尾相互重叠,在这种情况下,从4开始即从前往后copy是没有问题的,因为在覆盖4 5两个位置之前,4 5 已经copy到1 2 的位置上了。
但是,假设现在要将1 2 3 4 5copy到4 5 6 7 8的位置上,这种情况下,假如从1开始从头copy,那么,当copy4 5这两个位置时,他们已经被1 2覆盖,此时,可以采用从后往前coppy的方法。
而memmove并不关心是哪种重叠,都可以避免这两种问题发生,这也是有别于memcpy的地方。
3.手动实现memmove
void * memmove ( void * destination, const void * source, size_t num );
其返回值为destination的指针。
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char* my_memmove(char* dst, const char* src, int num)
{
//目标的尾和源的头重叠
if (src < dst)
{
while (*src != '\0' && num--)
{
*dst++ = *src++;
}
}
//目标的头和源的尾重叠
else
{
int static_bytes = num;
(char*)dst += static_bytes - 1;
(char*)src += static_bytes - 1;
while (num--)
{
*(char*)dst = *(char*)src;
(char*)dst -= 1;
(char*)src -= 1;
}
}
return dst;
}
int main()
{
char str[] = "hello bit!";
//目标的尾和源的头重叠
/*char* dst = my_memmove(str, str + 2, 3);
printf("%s\n", dst);*/
//目标的头和源的尾重叠
char* dst = my_memmove(str + 2, str, 3);
printf("%s\n", dst);
return 0;
}