使用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().如果区域可能重叠,您应该使用它,因为它考虑到了这种可能性.