函数原型:void *memmove(void *dest, const void *source, size_t count) 返回值说明:返回指向dest的void *指针
参数说明:dest,source分别为目标串和源串的首地址。count为要移动的字符的个数 函数说明:memmove用于从source拷贝count个字符到dest,如果目标区域和源区域有重叠的话,memmove能够保证源串在被覆盖之前将重叠区域的字节拷贝到目标区域中。
2.memcpy
函数原型:void *memcpy(void *dest, const void *source, size_t count); 返回值说明:返回指向dest的void *指针
函数说明:memcpy功能和memmove相同,但是memcpy中dest和source中的区域不能重叠,否则会出现未知结果。
3.两者区别
函数memcpy()从source指向的区域向dest指向的区域复制count个字符,如果两数组重叠,不定义该函数的行为。
而memmove(),如果两函数重叠,赋值仍正确进行。
memcpy函数假设要复制的内存区域不存在重叠,如果你能确保你进行复制操作的的内存区域没有任何重叠,可以直接用memcpy;如果你不能保证是否有重叠,为了确保复制的正确性,你必须用memmove。
memcpy的效率会比memmove高一些,如果还不明白的话可以看一些两者的实现:
1. memcpy 2. 代码:
;***
;memcpy.asm - contains memcpy and memmove routines ;
; Copyright (c) 1986-1997, Microsoft Corporation. All right reserved. ;
;Purpose:
; memcpy() copies a source memory buffer to a destination buffer. ; Overlapping buffers are not treated specially, so propogation may occur.
; memmove() copies a source memory buffer to a destination buffer. ; Overlapping buffers are treated specially, to avoid propogation. ;
;******************************************************************************* ;***
;memcpy - Copy source buffer to destination buffer ;
;Purpose:
; memcpy() copies a source memory buffer to a destination memory buffer.
; This routine does NOT recognize overlapping buffers, and thus can lead
; to propogation.
; For cases where propogation must be avoided, memmove() must be used. ;
; Algorithm:
3. void* memcpy(void* dest, void* source, size_t count) 4. {
5. assert(NULL != source && NULL != dest); 6. void* ret = dest;
7. //copy from lower address to higher address 8. while (count--)
9. *dest++ = *source; 10.
11. return ret; 12. } 13. 14. memmove
15. memmove - Copy source buffer to destination buffer
;
;Purpose:
; memmove() copies a source memory buffer to a destination memory buffer.
; This routine recognize overlapping buffers to avoid propogation. ; For cases where propogation is not a problem, memcpy() can be used. ;
; Algorithm:
16. void* memmove(void* dest, void* source, size_t count) 17. {
18. assert(NULL != source && NULL != dest); 19. void* ret = dest; 20.
21. if (dest<= source || dest>= (source + count)) 22. {
23. //Non-Overlapping Buffers
//copy from lower addresses to higher addresses
24. while (count --)
25. *dest++ = *source++; 26. } 27. else 28. {
29. //Overlapping Buffers
//copy from higher addresses to lower addresses 30. dest += count - 1; 31. source += count - 1; 32. while (count--)
33. *dest-- = *source--; 34. }
35. return ret; 36. } 区别:
从DESCRIPTION看来,两者的功能基本相同,唯一不同的是,当 dest 和 src 有重叠的时候选用不同的函数可能会造成不同的结果。不妨写个小程序来测一下: 0 #i nclude 3 int main() 4 { 5 int i = 0; 6 int a[10]; 7 8 for(i; i < 10; i++) 9 { 10 a[i] = i; 11 } 12 13 memcpy(&a[4], a, sizeof(int)*6); 14 15 for(i = 0; i < 10; i++) 16 { 17 printf(\"%d \18 } 20 21 printf(\"\\n\"); 22 return 0; 23 } 很简单的小程序!不过已经足以达到我的目的了:)将上面代码gcc之后再运行,结果为:0 1 2 3 0 1 2 3 0 1 。 再把第13行改成:memmove(&a[4], a, sizeof(int)*6),重新gcc再运行,结果为:0 1 2 3 0 1 2 3 4 5 ! 呵呵,两者的区别出现了。不过其实这样还不够,继续修改13行: memmove(a, &a[4], sizeof(int)*6) //也就是将源、目的置换一下而已 重新gcc编译再运行,结果为:4 5 6 7 8 9 6 7 8 9 。 还不够,继续修改13行为: memcpy(a, &a[4], sizeof(int)*6); gcc并运行,结果仍为: 4 5 6 7 8 9 6 7 8 9 ! 至此真相已经大白了。对比上面四个结果,不难得出以下结论: 1. 当 src 和 dest 所指内存区有重叠时,memmove 相对 memcpy 能提供保证:保证能将 src 所指内存区的前 n 个字节正确的拷贝到 dest 所指内存中; 2. 当 src 地址比 dest 地址低时,两者结果一样。换句话说,memmove 与 memcpy 的区别仅仅体现在 dest 的头部和 src 的尾部有重叠的情况下。 因篇幅问题不能全部显示,请点此查看更多更全内容