user-0 提问: memcpy（）求解

回复:
user: user-1
content: 599 void *memcpy(void *dest, const void *src, size_t count) 600 { 601         char *tmp = dest; 602         const char *s = src; 603  604         while (count--) 605                 *tmp++ = *s++; 606         return dest; 607 }  这个是常用的string.c中的源码，如果效率要求苛刻用kernel的  32 static __always_inline void *__memcpy(void *to, const void *from, size_t n)  33 {  34         int d0, d1, d2;  35         asm volatile("rep ; movsl\n\t"  36                      "movl %4,%%ecx\n\t"  37                      "andl $3,%%ecx\n\t"  38                      "jz 1f\n\t"  39                      "rep ; movsb\n\t"  40                      "1:"  41                      : "=&c" (d0), "=&D" (d1), "=&S" (d2)  42                      : "" (n / 4), "g" (n), "1" ((long)to), "2" ((long)from)  43                      : "memory");  44         return to;  45 }

user: user-2
content: 引用 5 楼 u013431701 的回复:[quote=引用 2 楼 derekrose 的回复:] 去看memcpy的函数头  没看明白求教， 不支持重叠，得出错误结果才对啊，现在得出正确的结果了，我就不明白了.[/quote]  真相是这样的，有些memcpy的实现，是不判断方向的，就不支持重叠区， 但是有些实现是判断方向的，支持重叠区，就如30楼的那样的实现， BSD 的实现也是支持重叠区的 http://svnweb.freebsd.org/base/release/9.2.0/lib/libc/string/bcopy.c?revision=255898&view=markup  但是标准里说的是  4.11.2.1 The memcpy function Synopsis  #include <string.h> void *memcpy(void *s1, const void *s2, size_t n); Description  The memcpy function copies n characters from the object pointed to by s2 into the object pointed to by s1. If copying takes place between objects that overlap, the behavior is undefined. Returns  The memcpy function returns the value of s1.

user: user-3
content: 旧源的内容都被改变了！谁说源和目标重叠时memcpy是对的我跟他急！！

user: user-4
content: char t[10] = {'A','B','C','D','E'}； 初始化没有结束符，不太妥吧

user: user-5
content: 引用 36 楼 lm_whales 的回复:memcpy 是 ，复制一份，完全相同的数据，到另一块内存。 前置条件是两块内存无重叠。 至于重叠了，结果如何，实际上相当于未定义行为，任何结果都是对的。  这才是正解！ 参考msdn：http://msdn.microsoft.com/zh-cn/library/dswaw1wk%28v=vs.90%29.aspx   memcpy copies count bytes from src to dest; wmemcpy copies count wide characters (two bytes). If the source and destination overlap, the behavior of memcpy is undefined. Use memmove to handle overlapping regions.

user: user-6
content: memcpy 是 ，复制一份，完全相同的数据，到另一块内存。 前置条件是两块内存无重叠。 至于重叠了，结果如何，实际上相当于未定义行为，任何结果都是对的。

user: user-7
content: @u012997273 看起来memmove.asm=memcpy.asm，但是内存重叠还是memmove吧，貌似release版时memcpy代码不按上面的会出问题...

user: user-8
content: 用debugger跟踪

user: user-9
content: 技术都是在进步的, 最简单直接的办法是调试查看它到底是怎么计算的, 程序执行到memcpy的时候按F11进入, 就可看到源码或者反汇编代码.

user: user-10
content: memcpy不支持内存重叠。

user: user-11
content: 买了amd的cpu，amd说如果超频，是不保证不会烧掉cpu，amd没有对超频做特殊处理，但是我超频了，结果不是逾期的啊，求指教.

user: user-12
content: void * __cdecl memmove (         void * dst,         const void * src,         size_t count         ) {         void * ret = dst;  #if defined (_M_IA64) || defined (_M_AMD64)          {           __declspec(dllimport)           void RtlMoveMemory( void *, const void *, size_t count );          RtlMoveMemory( dst, src, count );          }  #else  /* defined (_M_IA64) || defined (_M_AMD64) */         if (dst <= src || (char *)dst >= ((char *)src + count)) {                 /*                  * Non-Overlapping Buffers                  * copy from lower addresses to higher addresses                  */                 while (count--) {                         *(char *)dst = *(char *)src;                         dst = (char *)dst + 1;                         src = (char *)src + 1;                 }         }         else {                 /*                  * Overlapping Buffers                  * copy from higher addresses to lower addresses                  */                 dst = (char *)dst + count - 1;                 src = (char *)src + count - 1;                  while (count--) {                         *(char *)dst = *(char *)src;                         dst = (char *)dst - 1;                         src = (char *)src - 1;                 }         } #endif  /* defined (_M_IA64) || defined (_M_AMD64) */          return(ret); }  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-12
content: C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\crt\src\intel\memcpy.asm C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\crt\src\intel\memmove.asm 你看看这两个文件的内容，我的是vc 2010，是这个目录

user: user-12
content: 引用 10 楼 u013431701 的回复:[quote=引用 7 楼 u012997273 的回复:] [quote=引用 6 楼 u012997273 的回复:] d = （char *）memcpy（&t[0],&t[1]，2）； 就看的清楚了 错了，用int代替char试试[/quote]  d = （char *）memcpy（&t[0],&t[1]，2）； 返回的是数组t的首地址，和int型没有关系吧.[/quote] 不好意思，刚才我还以为是memcpy内部做了4字节优化了， 跟踪了下发现，其实memcpy最终调用的却是memmove函数， 环境:vc 2010

user: user-13
content: memcpy就是直接用你传递到里面的字符串参数进行拷贝，所以是没有处理内存重叠的，就会得到AAADE 而memmove是把地址参数拷贝了一份字符串，然后进行拷贝，这就是处理了内存重叠，就会得到AABDE 这样说应该可以理解了吧

user: user-0
content: 引用 9 楼 xihu1364 的回复:如果没有处理内存重叠，   不是应该是  t[0] = 'A';  t[1] = 'A';  t[2] = 'A';  吗？  结果应该是AAADE吗?   求解   不知道楼主怎么想的，怎么会是这个结果呢 ABCDE     t[1]是B开始           1   ABCDE    t[0]是A开始            2  蓝色代替红色 不就是最终结果 引用 9 楼 xihu1364 的回复:如果没有处理内存重叠，   不是应该是  t[0] = 'A';  t[1] = 'A';  t[2] = 'A';  吗？  结果应该是AAADE吗?   求解   不知道楼主怎么想的，怎么会是这个结果呢 ABCDE     t[1]是B开始           1   ABCDE    t[0]是A开始            2  蓝色代替红色 不就是最终结果  （char *）memcpy（&t[1],&t[0]，2） 把t[0]的内容copy到t[1]中， 不应是t[0]的内容不变，A， t[1]的内容变为A， 再把t[1]的内容copy到t[2], t[2]变为A，就结束了，有问题吗？

user: user-0
content: 引用 7 楼 u012997273 的回复:[quote=引用 6 楼 u012997273 的回复:] d = （char *）memcpy（&t[0],&t[1]，2）； 就看的清楚了 错了，用int代替char试试[/quote]  d = （char *）memcpy（&t[0],&t[1]，2）； 返回的是数组t的首地址，和int型没有关系吧.

user: user-14
content: 如果没有处理内存重叠，   不是应该是  t[0] = 'A';  t[1] = 'A';  t[2] = 'A';  吗？  结果应该是AAADE吗?   求解   不知道楼主怎么想的，怎么会是这个结果呢 ABCDE     t[1]是B开始           1   ABCDE    t[0]是A开始            2  蓝色代替红色 不就是最终结果

user: user-0
content: 引用 6 楼 u012997273 的回复:d = （char *）memcpy（&t[0],&t[1]，2）； 就看的清楚了  什么意思，没懂啊.

user: user-12
content: 引用 6 楼 u012997273 的回复:d = （char *）memcpy（&t[0],&t[1]，2）； 就看的清楚了 错了，用int代替char试试