memmove不动

时间:2010-12-18 20:50:55

标签: c++ c memory libc

memmove没有真正移动内存不对吗?它只是将内存从一个区域复制到另一个区域,并允许这两个区域重叠。我问这个问题是因为我只是想知道为什么这个fnc以非常误导的方式被调用 因为我明白当某个东西从一个地方移动到另一个地方时,“东西”就是在另一个地方而不是第一个地方之后。而memmove它不会那样工作。我是对的吗?

7 个答案:

答案 0 :(得分:9)

你是对的,它会复制它。但是,memmovememcpy之间存在差异,因为memmove可以正确处理缓冲区重叠时的情况,因此在这些情况下建议使用。

但是,由于memmove执行的额外检查,当缓冲区很小且肯定不重叠时,memcpy更好。

答案 1 :(得分:6)

memcpy()memmove()之间的区别在于memmove()始终可以安全使用,无论源和目标之间是否存在别名。好像memmove()首先将数据复制到临时缓冲区然后再复制到目标。 memcpy()不提供任何别名保证。 可能按预期工作,但可能不是。如果您知道缓冲区不能重叠,memcpy()就可以了,并且可以在任何给定的库中使用允许它比memmove()更快的优化。在另一个库memcpy()实际上可能只是memmove()

如果你知道src和dst不能是别名,那么使用memcpy()是安全的。如果您不知道哪一个适用于您,请使用memmove()

答案 2 :(得分:5)

该函数的名称是这样的,因为如果正在复制的内存区域执行碰巧重叠,它不再是副本,因为原始缓冲区不再是未更改的。因此,原始缓冲区应被视为不可用。由于您使用的是memmove而不是memcpy,因此可能就是这种情况。因此,命名是有意义的:从语义上讲,您正在移动数据而不是复制数据。

答案 3 :(得分:4)

Memmove 数据从源复制到目标。它与memcpy的不同之处在于它可以保证在重叠的内存区域上工作。

答案 4 :(得分:3)

是的,memmove真的是memcpy,能够处理重叠的块。假设您有一个数组,并且您希望在开头插入一些新项目(或删除一些项目),然后在语法上你正在做的是“移动”(现有的或剩余的)项目来回 - 我猜,并且在这种情况下,这个名字是有道理的。

答案 5 :(得分:3)

是的,memmove是副本的另一种变体。它不会“移动”内存,因为原始字节不再是操作之前的字节。它专门用于处理重叠内存的情况。

如何完成这取决于您的架构,但我已经看到它以两种不同的方式完成:

  • 使用具有两个memcpy类型操作的临时缓冲区;或
  • 从前进的第一个字节或向后的最后一个字节进行复制,具体取决于重叠类型(如果有的话)。

答案 6 :(得分:0)

回答关于memmove()名称的问题:我认为这个名称的目的是反映支持将数组中的元素移动到数组中的另一个范围(例如,为新的空间腾出空间)数组的开头或数组内部。)

正如其他答案所述,memcpy()可以使用memmove()无法使用的优化技术,因为memcpy()不支持重叠的内存区域,而memmove()则。

您可能需要考虑的一件事是默认情况下仍然使用memmove()而不是memcpy(),除非您正在处理复制性能至关重要的应用程序。 memcpy()可以提供更好的性能(主要是因为它可以更有效地内联,我认为),但请记住this quote about the memcpy() implementation in the Linux kernel关于应用程序错误使用C库的memcpy():< / p>

  

在内核中,我们使用的优化x86 memcpy实际上是一个memmove(),因为虽然性能非常重要,但重复性和避免意外(严格来说,我们有两个:案例的“rep movs”版本)应该是快速的,以及开放编码的复制版本。“rep movs”版本仅向前,不处理重叠区域。