这个问题已经在这里有一个答案:
我使用的阿兹台克人解线性方程组库时碰到了奇怪的行为。使用Valgrind的,我发现,这个库确实对重叠缓冲区一个memcpy
。规范中说,重叠的缓冲区memcpy
的行为没有定义。
事实证明,在多台机器memcpy
具有相同的行为,如果你会用它做for循环,因此,你可以安全地从一个更高的来源,以较低的目的地复制:
for(int i = 0; i < len; i ++)
dest[i] = source[i];
但是,我们的大型集群上,重叠缓冲区memcpy
具有不同的行为导致的问题。
现在我不知道在图书馆重叠memcpy
是否正常,或者只是在我的代码中的另一个错误引起的。由于库被广泛应用于我假设memcpy
问题应更早发现。在另一方面,它仍然可能是绝大多数memcpy
实现的行为类似于for循环,因此没有人遇到过这个问题。
memcpy
经验?memcpy
?我想指出的是,一个问题是关于不同的实施方式,不是关于规范说什么实践经验。
我已经做了一些研究,这在过去...在Linux上,直到最近,memcpy()
实施的方式是相似,足以memmove()
是重叠的记忆是不是问题的工作,在我的经验,其他UNIXs是相同的。这不会改变,这是根据标准定义的操作的事实,而你只是幸运,在某些平台上有时工作 - 和memmove()
是标准支持的正确答案。
然而,在2010年,glibc的维护者推出了一个新的,优化的memcpy()
,改变memcpy()
的行为,其中C标准库编译要快一些英特尔的核心类型,但不再就像memmove()
[1]。 (I似乎也指出,这仅用于存储段大于80个字节触发新的代码)。有趣的是,这引起了之类的东西了Linux版本的Adobe Flash播放器打破[2],以及其他一些开放源代码包(早在2010年时,Fedora Linux系统成为第一个采用改变memcpy()
中的glibc)。
memcpy()
不支持重叠的内存。这使得如果缓冲区不重叠,这是行不通的优化。
没有太多真正审视但是进入,因为C提供了不支持重叠内存替代:memmove()
。它的用法是相同的memcpy()
。你应该使用它,如果这些区域是重叠的,因为它占了这种可能性。