重叠的缓冲区的memcpy [重复]

问题描述 投票:12回答:3

这个问题已经在这里有一个答案:

我使用的阿兹台克人解线性方程组库时碰到了奇怪的行为。使用Valgrind的,我发现,这个库确实对重叠缓冲区一个memcpy。规范中说,重叠的缓冲区memcpy的行为没有定义。

事实证明,在多台机器memcpy具有相同的行为,如果你会用它做for循环,因此,你可以安全地从一个更高的来源,以较低的目的地复制:

for(int i = 0; i < len; i ++)
  dest[i] = source[i];

但是,我们的大型集群上,重叠缓冲区memcpy具有不同的行为导致的问题。

现在我不知道在图书馆重叠memcpy是否正常,或者只是在我的代码中的另一个错误引起的。由于库被广泛应用于我假设memcpy问题应更早发现。在另一方面,它仍然可能是绝大多数memcpy实现的行为类似于for循环,因此没有人遇到过这个问题。

  • 谁能告诉我关于他与各种机器重叠memcpy经验?
  • 我的哪个计算机系统的一部分并实际提供memcpy

我想指出的是,一个问题是关于不同的实施方式,不是关于规范说什么实践经验。

c++ c memcpy
3个回答
13
投票

我已经做了一些研究,这在过去...在Linux上,直到最近,memcpy()实施的方式是相似,足以memmove()是重叠的记忆是不是问题的工作,在我的经验,其他UNIXs是相同的。这不会改变,这是根据标准定义的操作的事实,而你只是幸运,在某些平台上有时工作 - 和memmove()是标准支持的正确答案。

然而,在2010年,glibc的维护者推出了一个新的,优化的memcpy(),改变memcpy()的行为,其中C标准库编译要快一些英特尔的核心类型,但不再就像memmove() [1]。 (I似乎也指出,这仅用于存储段大于80个字节触发新的代码)。有趣的是,这引起了之类的东西了Linux版本的Adobe Flash播放器打破[2],以及其他一些开放源代码包(早在2010年时,Fedora Linux系统成为第一个采用改变memcpy()中的glibc)。


12
投票

memcpy()不支持重叠的内存。这使得如果缓冲区不重叠,这是行不通的优化。

没有太多真正审视但是进入,因为C提供了不支持重叠内存替代:memmove()。它的用法是相同的memcpy()。你应该使用它,如果这些区域是重叠的,因为它占了这种可能性。


0
投票

memmove()可以用于该目的。 memcpy() [man-page]已与“源极”不应与目的地重叠条件定义。

为了更好地理解,你可以尝试了解memcpy()memmove(),通过尝试来定义它的版本。 [more info]

© www.soinside.com 2019 - 2024. All rights reserved.