memcpy重叠缓冲区

Mic*_*ael 12 c c++ memcpy

使用Aztec线性系统求解器库时,我遇到了奇怪的行为.使用valgrind,我发现这个库memcpy在重叠缓冲区上执行.规范说明memcpy没有定义重叠缓冲区的行为.

事实证明,memcpy在许多机器上具有与使用for循环一样的行为,因此您可以安全地从较高的源复制到较低的目标:

for(int i = 0; i < len; i ++)
  dest[i] = source[i];
Run Code Online (Sandbox Code Playgroud)

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

现在我想知道memcpy库中的重叠是正常的还是仅仅是由我的代码中的另一个错误引起的.由于库被广泛使用,我认为memcpy应该早先发现该问题.另一方面,绝大多数memcpy实现仍然可能像for循环一样,因此没有人遇到过这个问题.

  • 谁能告诉我他memcpy在各种机器上重叠的经历?
  • 我的计算机系统的哪一部分确实提供了memcpy

我想指出的问题是关于各种实现的实际经验,而不是规范所说的内容.

Joh*_*hnH 13

我在过去对此做了一些研究......在Linux上,直到最近,memcpy()memmove()与重叠内存相似的方式工作的实现不是问题,根据我的经验,其他UNIXs我们是一样的.这并没有改变这一事实,即根据标准这是未定义的行为,你很幸运,在某些平台上它有时可行 - 并且memmove()是标准支持的正确答案.

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


Fat*_*ror 12

memcpy()不支持重叠内存.这允许在缓冲区重叠时不起作用的优化.

没有太多真正审视但是进入,因为C提供了另一种支持重叠内存:memmove().它的用法与之相同memcpy().如果区域可能重叠,您应该使用它,因为它考虑到了这种可能性.

  • 如果您发现该库正在进行此类调用,则它是1)库本身中的错误,或2)库如何使用的错误,使得不应该重叠的内存.但是,有些情况下它*可以*工作,但并不会使它成为一个错误. (2认同)