Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/159.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 重叠缓冲区的memcpy_C++_C_Memcpy - Fatal编程技术网

C++ 重叠缓冲区的memcpy

C++ 重叠缓冲区的memcpy,c++,c,memcpy,C++,C,Memcpy,使用Aztec线性系统解算器库时,我遇到了奇怪的行为。使用valgrind,我发现这个库对重叠的缓冲区执行memcpy。规范指出,memcpy在重叠缓冲区上的行为未定义 事实证明,许多机器上的memcpy具有与使用for循环相同的行为,因此可以安全地从较高的源复制到较低的目标: for(int i = 0; i < len; i ++) dest[i] = source[i]; for(int i=0;i

使用Aztec线性系统解算器库时,我遇到了奇怪的行为。使用valgrind,我发现这个库对重叠的缓冲区执行
memcpy
。规范指出,
memcpy
在重叠缓冲区上的行为未定义

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

for(int i = 0; i < len; i ++)
  dest[i] = source[i];
for(int i=0;i
但是在我们的大型集群上,重叠缓冲区的
memcpy
有不同的行为,这会导致问题

现在我想知道库中的重叠
memcpy
是正常的还是我的代码中的另一个bug造成的。由于该库被广泛使用,我假设
memcpy
问题应该更早发现。另一方面,仍有可能绝大多数
memcpy
实现的行为类似于for循环,因此没有人遇到过这个问题

  • 有人能告诉我他在各种机器上使用重叠
    memcpy
    的经验吗
  • 我的计算机系统的哪个部分实际上提供了
    memcpy
我想指出的是,问题是关于各种实现的实际经验,而不是规范中所说的。

memcpy()
不支持重叠内存。这允许在缓冲区重叠的情况下进行不起作用的优化


但是,没有太多需要研究的内容,因为C提供了一种支持重叠内存的替代方法:
memmove()
。它的用法与
memcpy()
相同。如果区域可能重叠,您应该使用它,因为它说明了这种可能性。

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

然而,在2010年,glibc维护人员推出了一种新的优化的
memcpy()
,它改变了
memcpy()
对于某些英特尔核心类型的行为,其中C标准库的编译速度更快,但不再像
memmove()
[1]那样工作。(我似乎还记得,这是仅针对大于80字节的内存段触发的新代码)。有趣的是,这导致Adobe Flash player的Linux版本以及其他几个开源软件包(早在2010年,Fedora Linux成为第一个在glibc中采用经过更改的
memcpy()
的软件包)都崩溃了[2]

  • [1]
  • [2]
memmove()
可用于此目的
memcpy()
[]的定义条件是“源”不应与目标重叠


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

规范对此很清楚。但是我想知道库是否经常执行这样的
memcpy
,而且没有人遇到过这个问题,因为绝大多数实现的行为都像for循环,或者我只是假设驱动库的代码中有一个bug。如果你发现库发出这样的调用,那就是1)库本身有一个bug,或者2)库如何使用的错误,导致不应该重叠的内存无法使用。但是,在某些情况下它确实有效,这并不意味着它不是一个bug。请提供一个最小的示例,以便我们能够重现您的问题,并让您知道bug是否在库中或代码中。我从未了解memcpy的这个问题。当然,这只是一个比较,以确定您是否需要从源缓冲区的顶部或底部进行复制?@Martin James很久以前和很久以前,大量使用的
memcpy()
的优先级迫使它非常精简。按照当时的标准,“一个比较”是臃肿的软件,通常不需要——而且它阻止了某些优化。它只是减慢了系统的速度。因此诞生了
memmove()
@chux orite,谢谢:)这正是我想要的答案。因此,这种行为很有可能在该库中存在多年,从未引起问题……完全正确。当我将旧代码移动到带有新更改的新服务器时,我被它咬了一口。