user-0 提问: memcpy内存重叠问题

回复:
user: user-1
content: 引用 1 楼 zhao4zhong1 的回复:先弄清楚copy和move的语义： copy的语义是操作结束后，新目的的内容和旧源的内容一致，且保证旧源的内容不变。 move的语义是操作结束后，新目的的内容和旧源的内容一致，但不保证旧源的内容不变。  于是乎，当操作的内存重叠时，无论如何也不可能实现copy！  +1+1+1+1+1

user: user-2
content: 引用 4 楼 chuansunshine 的回复: /*** *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. * *Entry: *       void *dst = pointer to destination buffer *       const void *src = pointer to source buffer *       size_t count = number of bytes to copy * *Exit: *       Returns a pointer to the destination buffer * *Exceptions: *******************************************************************************/  void * __cdecl memcpy (         void * dst,         const void * src,         size_t count         ) {         void * ret = dst;  #if defined (_M_IA64)          {           __declspec(dllimport)           void RtlCopyMemory( void *, const void *, size_t count );          RtlCopyMemory( dst, src, count );          }  #else  /* defined (_M_IA64) */         /*          * copy from lower addresses to higher addresses          */         while (count--) {                 *(char *)dst = *(char *)src;                 dst = (char *)dst + 1;                 src = (char *)src + 1;         } #endif  /* defined (_M_IA64) */          return(ret); }有兴趣可以翻到 C:\Program Files\Microsoft Visual Studio 10.0\VC\crt\src\intel 里看看 memcpy.asm 的实现 实际上通常情况下 这种版本 c 代码 不会出现在实际使用中

user: user-2
content: memcpy 的具体实现很复杂的 ... 在数据量达/mem 16字节的对齐的情况下 会使用 movdqa 来拷贝 u/v 管道配对也是非常精准 ... 这种程度的 memcpy 没法跟系统比的 ... release 版本下 最多也就是 rep movsd 程度的优化 ...

user: user-3
content: 直接转到定义， 看看怎么实现的

user: user-3
content: /*** *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. * *Entry: *       void *dst = pointer to destination buffer *       const void *src = pointer to source buffer *       size_t count = number of bytes to copy * *Exit: *       Returns a pointer to the destination buffer * *Exceptions: *******************************************************************************/  void * __cdecl memcpy (         void * dst,         const void * src,         size_t count         ) {         void * ret = dst;  #if defined (_M_IA64)          {           __declspec(dllimport)           void RtlCopyMemory( void *, const void *, size_t count );          RtlCopyMemory( dst, src, count );          }  #else  /* defined (_M_IA64) */         /*          * copy from lower addresses to higher addresses          */         while (count--) {                 *(char *)dst = *(char *)src;                 dst = (char *)dst + 1;                 src = (char *)src + 1;         } #endif  /* defined (_M_IA64) */          return(ret); }

user: user-3
content: /*** *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. * *Entry: *       void *dst = pointer to destination buffer *       const void *src = pointer to source buffer *       size_t count = number of bytes to copy * *Exit: *       Returns a pointer to the destination buffer * *Exceptions: *******************************************************************************/  void * __cdecl memcpy (         void * dst,         const void * src,         size_t count         ) {         void * ret = dst;  #if defined (_M_IA64)          {           __declspec(dllimport)           void RtlCopyMemory( void *, const void *, size_t count );          RtlCopyMemory( dst, src, count );          }  #else  /* defined (_M_IA64) */         /*          * copy from lower addresses to higher addresses          */         while (count--) {                 *(char *)dst = *(char *)src;                 dst = (char *)dst + 1;                 src = (char *)src + 1;         } #endif  /* defined (_M_IA64) */          return(ret); } 自己看吧，亲

user: user-4
content: 先弄清楚copy和move的语义： copy的语义是操作结束后，新目的的内容和旧源的内容一致，且保证旧源的内容不变。 move的语义是操作结束后，新目的的内容和旧源的内容一致，但不保证旧源的内容不变。  于是乎，当操作的内存重叠时，无论如何也不可能实现copy！

user: user-5
content: memcpy： To avoid overflows, the size of the arrays pointed by both the destination and source parameters, shall be at least num bytes, and should not overlap (for overlapping memory blocks, memmove is a safer approach).