1,memmove函数功能介绍:
移动内存块
将字节数的值从源指向的位置复制到目标指向的内存块。复制就像使用了中间缓冲区一样,允许目标和源重叠。
源指针和目标指针指向的对象的基础类型与此函数无关;结果是数据的二进制副本。
该函数不检查源中的任何终止空字符 - 它总是准确地复制字节数。
为避免溢出,目标参数和源参数指向的数组的大小应至少为字节数。
2,例子:
/* memmove example */
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "memmove can be very useful......";
memmove (str+20,str+15,11);
puts (str);
return 0;
}
输出的结果为:
3,详细介绍复制的内存块重叠的情况:
在同一个数组中,我们要将红色框中五个数拷贝到绿色框的位置,如果我们一如既往的从左到右的拷贝数据,那么数据将会出现丢失的情况。
这样先将1和2拷贝过去红色框中的后两位还没拷贝数据就已经发生了变化,最后结果如下。
要解决这个问题就需要将拷贝的顺序变为从后到前来拷贝,但是同理,如果想将绿色框中的数据拷贝到红色框,拷贝顺序是从后到前的话同样就会出现数据丢失的情况,所以我们在拷贝之前需要对两个指针的位置结合拷贝的的大小综合进行判断。
这样就可以分为两个情况,将两个指针比较之后再就行拷贝。
/* my_memmove example */
#include <stdio.h>
#include <assert.h>
#include <string.h>
char* my_memmove(void* p1, const void* p2, size_t len) {
assert(p1);
assert(p2);
void* ret = p1;
if (p1< p2) {
while (len--){
*(char*)p1 = *(char*)p2;
p1 = (char*)p1 + 1;
p2 = (char*)p2 + 1;
}
}
else {
while (len--) {
*((char*)p1 + len)= *((char*)p2+len);
}
}
}
int main() {
char str[] = "memmove can be very useful......";
my_memmove(str + 20, str + 15, 11);
puts(str);
return 0;
}