memcpy函数是不是已经解决了内存重叠的问题呢?

时间:2023-01-20 16:55:57
  1 #include <stdio.h>
  2 #include <string.h>
  3 
  4 int main(void)
  5 {   
  6     int i;
  7     char a[] = "12345";
  8     
  9     memcpy(a + 1, a, 3);
 10     for (i = 0; i < 5; i++)
 11         printf("a[%d] = %c\n", i, a[i]);
 12     
 13     return 0;
 14 }

输出结果:
a[0] = 1
a[1] = 1
a[2] = 2
a[3] = 3
a[4] = 5

不是应该是下面的结果吗?请高手指点,感激不尽!
a[0] = 1
a[1] = 1
a[2] = 1
a[3] = 1
a[4] = 5

39 个解决方案

#1


若内存有重叠,请用memmove.

#2


请用memmove,任何C库都保证解决内存重叠

#3


谢谢,我是在做试验。就是不知道为什么不是的下面的结果?

#4


void *memcpy(void *dest, const void *src, size_t n); 功能 从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址
怎么也得不出 1 1 1 1 5啊?

#5


memcpy函数不是单个字节复制的吗?
请问它是不是这样的工作过程呢:

第一次复制a[0]到a[1],结果a[1] = 1;
第二次把a[1]复制到a[2], 结果a[2] = 1;
第三次把a[2]复制到a[3], 结果a[3] = 1;

所以最后结果为:
a[0] = 1
a[1] = 1
a[2] = 1
a[3] = 1
a[4] = 5

请问帮忙解决疑惑,谢谢啦!

#6


原型:
void *memcpy(void *dest, const void *source, size_t count)
{
assert((NULL != dest) && (NULL != source));
char *tmp_dest = (char *)dest;
char *tmp_source = (char *)source;
while(count --)//不对是否存在重叠区域进行判断
*tmp_dest ++ = *tmp_source ++;
return dest;
}
http://blog.csdn.net/feitianxuxue/article/details/7195158

#7



If copying takes place between objects that overlap, the behavior is undefined.

$ cat overlap.c
#include <stdio.h>
#include <string.h>

int main(void)
{
        int i;
        char a[] = "12345";

        memcpy(a + 1, a, 3);
        for (i = 0; i < 5; i++)
        printf("a[%d] = %c\n", i, a[i]);
        return 0;
}
$ make && ./main.out
make: `main.out' is up to date.
a[0] = 1
a[1] = 1
a[2] = 1
a[3] = 3
a[4] = 5
$

#8


gcc运行结果是 1 1 2 2 5

#9


您好,7楼,谢谢了,能解释下输出结果吗?
a[3]不是也应该等于1吗?

#10


;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:
;
;           Same as memmove. See Below
;
;
;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:
;
;       void * memmove(void * dst, void * src, size_t count)
;       {
;               void * ret = dst;
;
;               if (dst <= src || dst >= (src + count)) {
;                       /*
;                        * Non-Overlapping Buffers
;                        * copy from lower addresses to higher addresses
;                        */
;                       while (count--)
;                               *dst++ = *src++;
;                       }
;               else {
;                       /*
;                        * Overlapping Buffers
;                        * copy from higher addresses to lower addresses
;                        */
;                       dst += count - 1;
;                       src += count - 1;
;
;                       while (count--)
;                               *dst-- = *src--;
;                       }
;
;               return(ret);
;       }
;
;
;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 in AX/DX:AX
;
;Uses:
;       CX, DX
;
;Exceptions:
;*******************************************************************************

#11


我的GCC编译结果是 1 1 2 3 5

#12


size(memcpy的第3个参数)要设置对。

#13


我的gcc版本:
gcc version 4.4.6 20110731 (Red Hat 4.4.6-3) (GCC)
 
编译结果是 1 1 2 3 5
感觉memcpy函数实现了memmove函数的功能。

不知道为什么?

#14


因为数组a是char型的,所以第三个参数设为3是没错的

#15


a[0] = 1
a[1] = 1
a[2] = 2
a[3] = 2
a[4] = 5
gcc (GCC) 4.1.2 20070925 (Red Hat 4.1.2-33)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

#16


这个与GCC应该没关系,而是与库有关系

#17


好,呵呵,谢谢xiaoxiao8310啦,就是结果怪怪的,不知道为什么,呵呵!

#18


请看x86的memcpy
libc库版本 release version 2.15,
其实是一样的和memmove。

#ifdef MEMCOPY
ENTRY(memcpy)
#else
#ifdef MEMMOVE
ENTRY(memmove)
#else
ENTRY(bcopy)
#endif
#endif
pushl %esi
pushl %edi
#if defined(MEMCOPY) || defined(MEMMOVE)
movl 12(%esp),%edi
movl 16(%esp),%esi
movl %edi, %eax
#else
movl 12(%esp),%esi
movl 16(%esp),%edi
#endif
movl 20(%esp),%ecx
movl %ecx,%edx
cmpl %esi,%edi /* potentially overlapping? */
jnb 1f
cld /* nope, copy forwards. */
shrl $2,%ecx /* copy by words */
rep
movsl
movl %edx,%ecx
andl $3,%ecx /* any bytes left? */
rep
movsb
popl %edi
popl %esi
ret
1:
addl %ecx,%edi /* copy backwards. */
addl %ecx,%esi
std
andl $3,%ecx /* any fractional bytes? */
decl %edi
decl %esi
rep
movsb
movl %edx,%ecx
shrl $2,%ecx
subl $3,%esi
subl $3,%edi
rep
movsl
popl %edi
popl %esi
cld
ret

#19


文档说,memcpy在发生内存重叠时,在语言中是未定义行为。

比如下面的代码也引发未定义行为
int i = 1;
i++ + i++ == ? /* ERROR */

#20


嗯,嗯,好,好,非常感谢大家!
thanks!

#21


“未定义”导致很奇怪!
引用 19 楼  的回复:
文档说,memcpy在发生内存重叠时,在语言中是未定义行为。

比如下面的代码也引发未定义行为
int i = 1;
i++ + i++ == ? /* ERROR */

#22


先把copy和move的概念分清楚吧:
copy的意思是操作结束后保证目标和旧源的数据一致,且旧源不会变;
move的意思是操作结束后保证目标和旧源的数据一致,但旧源不一定不变;

#23


赵老师一出手,我就明白了~~~~

速速膜拜赵老师

引用 22 楼  的回复:
先把copy和move的概念分清楚吧:
copy的意思是操作结束后保证目标和旧源的数据一致,且旧源不会变;
move的意思是操作结束后保证目标和旧源的数据一致,但旧源不一定不变;

#24


跟实现这个memcpy的库的实现方法有关吧

#25


未定义就是不可预期。你应该避免这样的情形,而不是去猜测它的结果。

Q: What's the difference between memcpy and memmove?

A: memmove offers guaranteed behavior if the memory regions pointed to by the source and destination arguments overlap. memcpy makes no such guarantee, and may therefore be more efficiently implementable. When in doubt, it's safer to use memmove. 

#26


有一函数,如  char * getMemery(){
     char * m = "212313";

   return m;

}

这个函数最大的问题是什么?如何才能改正确?
此外,m指向的常量存储区是否在函数调用结束后,就被释放掉了,还是要等程序结束后,才会被释放?

#27


引用 26 楼  的回复:
有一函数,如  char * getMemery(){
     char * m = "212313";

   return m;

}

这个函数最大的问题是什么?如何才能改正确?
此外,m指向的常量存储区是否在函数调用结束后,就被释放掉了,还是要等程序结束后,才会被释放?

字符串常量在整个应用程序运行期间只有一份拷贝。字符串常量的内存分配在只读存储区,是不可 改写的。
字符串的字面值是指向其首字符的指针。

返回一个指向只读存储区的地址,无法修改其内容。
显然该常量字符串所占的内存是程序运行结束后,释放的。

从函数的用意来看,好像是getMemory,分配内存,那么可以通过malloc, calloc(初始化),realloc(对malloc,calloc分配的内存再分配),注意,在外部要显示free()。

方法一: 使用静态数组

char * getMemery(){
  static char m[] = "212313";
 
  return m;

}




方法二: 使用动态内存分配


char * getMemery(){
  const char * str = "212313"
  char * m = malloc(strlen(str) + 1);
  memcpy(m, str, strlen(str)+1);

  return m;

}






#28


帮楼主顶下,……
求大侠解释memcpy函数。
从楼上提供的memcpy源代码,
运行结果应该是11115。
*a给*(a+1),即a[1]=a[0];1
*(a+1)给*(a+2),即a[2]=a[1];1
*(a+2)给*(a+3),即a[3]=a[2];1
实际运行结果咋是反的?
*(a+2)给*(a+3),即a[3]=a[2];3
*(a+1)给*(a+2),即a[2]=a[1];2
*a+给*(a+1),即a[1]=a[0];1
下面是参考memcpy改的,这个效果才是11235
void *mymemcpy(void *dest, const void *source, size_t count) 

assert((NULL != dest) && (NULL != source)); 
//char *tmp_dest = (char *)dest; 
//char *tmp_source = (char *)source; 
char *tmp_dest = (char *)dest + count - 1; 
char *tmp_source = (char *)source + count - 1; 
while(count --)
//*tmp_dest ++ = *tmp_source ++; 
    *tmp_dest -- = *tmp_source --; 
return dest; 

#29


赵老师说的有道理

#30


引用 22 楼  的回复:
先把copy和move的概念分清楚吧:
copy的意思是操作结束后保证目标和旧源的数据一致,且旧源不会变;
move的意思是操作结束后保证目标和旧源的数据一致,但旧源不一定不变;

提醒:按照这个理解的话,在内存有重叠时根本无法实现copy!

#31


引用 22 楼  的回复:
先把copy和move的概念分清楚吧:
copy的意思是操作结束后保证目标和旧源的数据一致,且旧源不会变;
move的意思是操作结束后保证目标和旧源的数据一致,但旧源不一定不变;


++

#32


看来不同的编译环境,所得结果是有差异的。
在32位X86平台上,每次copy一个字节需要一条指令,每次copy4个字节也只需要一条指令。
所以memcpy函数的实现尽可能4个字节4个字节的copy。

#33


引用 7 楼  的回复:
C/C++ code

If copying takes place between objects that overlap, the behavior is undefined.

$ cat overlap.c
#include <stdio.h>
#include <string.h>

int main(void)
{
        int i;
        char a[] ……


7 楼的答案可以用以下实现揭晓(该code摘自Linux 3.2.7)
执行第一次,此时类型为char,结果是: 11345
执行第二次,此时类型为short,结果为:11135

void * 

memcpy(void *pdst, const void *psrc, size_t pn)
{


  /* When src is aligned but not dst, this makes a few extra needless
     cycles.  I believe it would take as many to check that the
     re-alignment was unnecessary.  */
  if (((unsigned long) dst & 3) != 0
      /* Don't align if we wouldn't copy more than a few bytes; so we
 don't have to check further for overflows.  */
      && n >= 3)
  {
    if ((unsigned long) dst & 1)
      {
n--;
*dst = *src;
src++;
dst++;
      }

    if ((unsigned long) dst & 2)
      {
n -= 2;
*(short *) dst = *(short *) src;
src += 2;
dst += 2;
      }
  }

#34


还能回复结果吗

#35


我上次用memmove写一个buffer类
被公司新来的一位大拿说这种函数不能用的,效率非常低。。
我当时只能呵呵了

#36


引用 35 楼 q191201771 的回复:
我上次用memmove写一个buffer类
被公司新来的一位大拿说这种函数不能用的,效率非常低。。
我当时只能呵呵了


呵呵。 

#37


int main(void)
{
int i;
char a[] = "12345";
// 先做a[3] = a[2]的话,输出结果是:1 1 2 3 5
// 先做a[1] = a[0]的话,输出结果是:1 1 1 1 5
memcpy(a + 1, a, 3);
for (i = 0; i < 5; i++)
printf("a[%d] = %c\n", i, a[i]);
return 0;
}


看memcpy怎么实现的了。

#38


memcpy永远也解决不了内存重叠问题。因为:
copy操作的意思是操作完成后,目标的内容和旧源的内容一样, 且新源的内容也维持旧源的内容不变
move操作的意思是操作完成后,目标的内容和旧源的内容一样,新源的内容不一定维持旧源的内容不变。

#39


我这里的man page显示:
The memcpy() function copies n bytes from memory area s2 to memory area
     s1.  If s1 and s2 overlap,  behavior is undefined.  Applications in which
     s1 and s2 might overlap should use memmove(3) instead.
所以作为实现,它即可以不管overlap,也可以实现得像memmove一样。
所以,这个看库的实现。

#1


若内存有重叠,请用memmove.

#2


请用memmove,任何C库都保证解决内存重叠

#3


谢谢,我是在做试验。就是不知道为什么不是的下面的结果?

#4


void *memcpy(void *dest, const void *src, size_t n); 功能 从源src所指的内存地址的起始位置开始拷贝n个字节到目标dest所指的内存地址
怎么也得不出 1 1 1 1 5啊?

#5


memcpy函数不是单个字节复制的吗?
请问它是不是这样的工作过程呢:

第一次复制a[0]到a[1],结果a[1] = 1;
第二次把a[1]复制到a[2], 结果a[2] = 1;
第三次把a[2]复制到a[3], 结果a[3] = 1;

所以最后结果为:
a[0] = 1
a[1] = 1
a[2] = 1
a[3] = 1
a[4] = 5

请问帮忙解决疑惑,谢谢啦!

#6


原型:
void *memcpy(void *dest, const void *source, size_t count)
{
assert((NULL != dest) && (NULL != source));
char *tmp_dest = (char *)dest;
char *tmp_source = (char *)source;
while(count --)//不对是否存在重叠区域进行判断
*tmp_dest ++ = *tmp_source ++;
return dest;
}
http://blog.csdn.net/feitianxuxue/article/details/7195158

#7



If copying takes place between objects that overlap, the behavior is undefined.

$ cat overlap.c
#include <stdio.h>
#include <string.h>

int main(void)
{
        int i;
        char a[] = "12345";

        memcpy(a + 1, a, 3);
        for (i = 0; i < 5; i++)
        printf("a[%d] = %c\n", i, a[i]);
        return 0;
}
$ make && ./main.out
make: `main.out' is up to date.
a[0] = 1
a[1] = 1
a[2] = 1
a[3] = 3
a[4] = 5
$

#8


gcc运行结果是 1 1 2 2 5

#9


您好,7楼,谢谢了,能解释下输出结果吗?
a[3]不是也应该等于1吗?

#10


;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:
;
;           Same as memmove. See Below
;
;
;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:
;
;       void * memmove(void * dst, void * src, size_t count)
;       {
;               void * ret = dst;
;
;               if (dst <= src || dst >= (src + count)) {
;                       /*
;                        * Non-Overlapping Buffers
;                        * copy from lower addresses to higher addresses
;                        */
;                       while (count--)
;                               *dst++ = *src++;
;                       }
;               else {
;                       /*
;                        * Overlapping Buffers
;                        * copy from higher addresses to lower addresses
;                        */
;                       dst += count - 1;
;                       src += count - 1;
;
;                       while (count--)
;                               *dst-- = *src--;
;                       }
;
;               return(ret);
;       }
;
;
;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 in AX/DX:AX
;
;Uses:
;       CX, DX
;
;Exceptions:
;*******************************************************************************

#11


我的GCC编译结果是 1 1 2 3 5

#12


size(memcpy的第3个参数)要设置对。

#13


我的gcc版本:
gcc version 4.4.6 20110731 (Red Hat 4.4.6-3) (GCC)
 
编译结果是 1 1 2 3 5
感觉memcpy函数实现了memmove函数的功能。

不知道为什么?

#14


因为数组a是char型的,所以第三个参数设为3是没错的

#15


a[0] = 1
a[1] = 1
a[2] = 2
a[3] = 2
a[4] = 5
gcc (GCC) 4.1.2 20070925 (Red Hat 4.1.2-33)
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

#16


这个与GCC应该没关系,而是与库有关系

#17


好,呵呵,谢谢xiaoxiao8310啦,就是结果怪怪的,不知道为什么,呵呵!

#18


请看x86的memcpy
libc库版本 release version 2.15,
其实是一样的和memmove。

#ifdef MEMCOPY
ENTRY(memcpy)
#else
#ifdef MEMMOVE
ENTRY(memmove)
#else
ENTRY(bcopy)
#endif
#endif
pushl %esi
pushl %edi
#if defined(MEMCOPY) || defined(MEMMOVE)
movl 12(%esp),%edi
movl 16(%esp),%esi
movl %edi, %eax
#else
movl 12(%esp),%esi
movl 16(%esp),%edi
#endif
movl 20(%esp),%ecx
movl %ecx,%edx
cmpl %esi,%edi /* potentially overlapping? */
jnb 1f
cld /* nope, copy forwards. */
shrl $2,%ecx /* copy by words */
rep
movsl
movl %edx,%ecx
andl $3,%ecx /* any bytes left? */
rep
movsb
popl %edi
popl %esi
ret
1:
addl %ecx,%edi /* copy backwards. */
addl %ecx,%esi
std
andl $3,%ecx /* any fractional bytes? */
decl %edi
decl %esi
rep
movsb
movl %edx,%ecx
shrl $2,%ecx
subl $3,%esi
subl $3,%edi
rep
movsl
popl %edi
popl %esi
cld
ret

#19


文档说,memcpy在发生内存重叠时,在语言中是未定义行为。

比如下面的代码也引发未定义行为
int i = 1;
i++ + i++ == ? /* ERROR */

#20


嗯,嗯,好,好,非常感谢大家!
thanks!

#21


“未定义”导致很奇怪!
引用 19 楼  的回复:
文档说,memcpy在发生内存重叠时,在语言中是未定义行为。

比如下面的代码也引发未定义行为
int i = 1;
i++ + i++ == ? /* ERROR */

#22


先把copy和move的概念分清楚吧:
copy的意思是操作结束后保证目标和旧源的数据一致,且旧源不会变;
move的意思是操作结束后保证目标和旧源的数据一致,但旧源不一定不变;

#23


赵老师一出手,我就明白了~~~~

速速膜拜赵老师

引用 22 楼  的回复:
先把copy和move的概念分清楚吧:
copy的意思是操作结束后保证目标和旧源的数据一致,且旧源不会变;
move的意思是操作结束后保证目标和旧源的数据一致,但旧源不一定不变;

#24


跟实现这个memcpy的库的实现方法有关吧

#25


未定义就是不可预期。你应该避免这样的情形,而不是去猜测它的结果。

Q: What's the difference between memcpy and memmove?

A: memmove offers guaranteed behavior if the memory regions pointed to by the source and destination arguments overlap. memcpy makes no such guarantee, and may therefore be more efficiently implementable. When in doubt, it's safer to use memmove. 

#26


有一函数,如  char * getMemery(){
     char * m = "212313";

   return m;

}

这个函数最大的问题是什么?如何才能改正确?
此外,m指向的常量存储区是否在函数调用结束后,就被释放掉了,还是要等程序结束后,才会被释放?

#27


引用 26 楼  的回复:
有一函数,如  char * getMemery(){
     char * m = "212313";

   return m;

}

这个函数最大的问题是什么?如何才能改正确?
此外,m指向的常量存储区是否在函数调用结束后,就被释放掉了,还是要等程序结束后,才会被释放?

字符串常量在整个应用程序运行期间只有一份拷贝。字符串常量的内存分配在只读存储区,是不可 改写的。
字符串的字面值是指向其首字符的指针。

返回一个指向只读存储区的地址,无法修改其内容。
显然该常量字符串所占的内存是程序运行结束后,释放的。

从函数的用意来看,好像是getMemory,分配内存,那么可以通过malloc, calloc(初始化),realloc(对malloc,calloc分配的内存再分配),注意,在外部要显示free()。

方法一: 使用静态数组

char * getMemery(){
  static char m[] = "212313";
 
  return m;

}




方法二: 使用动态内存分配


char * getMemery(){
  const char * str = "212313"
  char * m = malloc(strlen(str) + 1);
  memcpy(m, str, strlen(str)+1);

  return m;

}






#28


帮楼主顶下,……
求大侠解释memcpy函数。
从楼上提供的memcpy源代码,
运行结果应该是11115。
*a给*(a+1),即a[1]=a[0];1
*(a+1)给*(a+2),即a[2]=a[1];1
*(a+2)给*(a+3),即a[3]=a[2];1
实际运行结果咋是反的?
*(a+2)给*(a+3),即a[3]=a[2];3
*(a+1)给*(a+2),即a[2]=a[1];2
*a+给*(a+1),即a[1]=a[0];1
下面是参考memcpy改的,这个效果才是11235
void *mymemcpy(void *dest, const void *source, size_t count) 

assert((NULL != dest) && (NULL != source)); 
//char *tmp_dest = (char *)dest; 
//char *tmp_source = (char *)source; 
char *tmp_dest = (char *)dest + count - 1; 
char *tmp_source = (char *)source + count - 1; 
while(count --)
//*tmp_dest ++ = *tmp_source ++; 
    *tmp_dest -- = *tmp_source --; 
return dest; 

#29


赵老师说的有道理

#30


引用 22 楼  的回复:
先把copy和move的概念分清楚吧:
copy的意思是操作结束后保证目标和旧源的数据一致,且旧源不会变;
move的意思是操作结束后保证目标和旧源的数据一致,但旧源不一定不变;

提醒:按照这个理解的话,在内存有重叠时根本无法实现copy!

#31


引用 22 楼  的回复:
先把copy和move的概念分清楚吧:
copy的意思是操作结束后保证目标和旧源的数据一致,且旧源不会变;
move的意思是操作结束后保证目标和旧源的数据一致,但旧源不一定不变;


++

#32


看来不同的编译环境,所得结果是有差异的。
在32位X86平台上,每次copy一个字节需要一条指令,每次copy4个字节也只需要一条指令。
所以memcpy函数的实现尽可能4个字节4个字节的copy。

#33


引用 7 楼  的回复:
C/C++ code

If copying takes place between objects that overlap, the behavior is undefined.

$ cat overlap.c
#include <stdio.h>
#include <string.h>

int main(void)
{
        int i;
        char a[] ……


7 楼的答案可以用以下实现揭晓(该code摘自Linux 3.2.7)
执行第一次,此时类型为char,结果是: 11345
执行第二次,此时类型为short,结果为:11135

void * 

memcpy(void *pdst, const void *psrc, size_t pn)
{


  /* When src is aligned but not dst, this makes a few extra needless
     cycles.  I believe it would take as many to check that the
     re-alignment was unnecessary.  */
  if (((unsigned long) dst & 3) != 0
      /* Don't align if we wouldn't copy more than a few bytes; so we
 don't have to check further for overflows.  */
      && n >= 3)
  {
    if ((unsigned long) dst & 1)
      {
n--;
*dst = *src;
src++;
dst++;
      }

    if ((unsigned long) dst & 2)
      {
n -= 2;
*(short *) dst = *(short *) src;
src += 2;
dst += 2;
      }
  }

#34


还能回复结果吗

#35


我上次用memmove写一个buffer类
被公司新来的一位大拿说这种函数不能用的,效率非常低。。
我当时只能呵呵了

#36


引用 35 楼 q191201771 的回复:
我上次用memmove写一个buffer类
被公司新来的一位大拿说这种函数不能用的,效率非常低。。
我当时只能呵呵了


呵呵。 

#37


int main(void)
{
int i;
char a[] = "12345";
// 先做a[3] = a[2]的话,输出结果是:1 1 2 3 5
// 先做a[1] = a[0]的话,输出结果是:1 1 1 1 5
memcpy(a + 1, a, 3);
for (i = 0; i < 5; i++)
printf("a[%d] = %c\n", i, a[i]);
return 0;
}


看memcpy怎么实现的了。

#38


memcpy永远也解决不了内存重叠问题。因为:
copy操作的意思是操作完成后,目标的内容和旧源的内容一样, 且新源的内容也维持旧源的内容不变
move操作的意思是操作完成后,目标的内容和旧源的内容一样,新源的内容不一定维持旧源的内容不变。

#39


我这里的man page显示:
The memcpy() function copies n bytes from memory area s2 to memory area
     s1.  If s1 and s2 overlap,  behavior is undefined.  Applications in which
     s1 and s2 might overlap should use memmove(3) instead.
所以作为实现,它即可以不管overlap,也可以实现得像memmove一样。
所以,这个看库的实现。