memcpy重叠不可理解

时间:2014-02-22 07:46:09

标签: c memcpy

我正在玩memcpy,以便更好地了解其工作,并且遇到了我无法理解的事情。

我从非常简单的代码开始:

char str [] = "0123456789abcdef";
memcpy(str + 5, str, 5);
puts(str);// prints 0123401234abcdef

这对我来说绝对可以理解。然后我继续说道:

char str [] = "0123456789abcdef";
memcpy(str + 5, str, 6);
puts(str); // 01234012340bcdef

首先我预计输出为01234012345bcdef,假设该函数将取前六个字符,但它再次从0开始。好吧,以为我,可能它以某种方式从已经构建的新字符串中获取字符。像这样memcpy(str + 5, str, 7);放7就证实了我的假设,因为它产生了012340123401cdef作为输出。

然而事情开始变得更加不清楚。如果我执行此操作memcpy(str + 5, str, 8);,则会输出0123401234567def !!!就像我从一开始就预期的那样。

我完全糊涂了。为什么这样做?好吧,我甚至可以理解打印01作为字符串的第11和第12个字符(但这不是我所期望的,我会感激解释)。但是,当我确定长度为8时,为什么会改变其行为?

我希望你明白我的意思。请提供详细说明。非常感谢提前

2 个答案:

答案 0 :(得分:3)

  

The memcpy() function shall copy n bytes 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.

memcpy假设源和目标不重叠。如果他们这样做,任何事情都可能发生,确切地说发生了什么可能取决于你使用的编译器,编译或运行的机器,你复制的区域有多大,一天中的什么时间等等。如果你想要的话要将内存块复制到与原始位置重叠的目标位置,请使用memmove

答案 1 :(得分:0)

memcpy()

  

[...]如果对象重叠,则行为未定义

您应该使用memmove()代替重叠案例。

  

[...]对象可能重叠:复制就像将字符复制到临时字符数组一样,然后将字符从数组复制到dest。