memcpy()vs memmove()
我试图理解
memcpy()
和memmove()
之间的区别,并且我已经阅读了memcpy()
没有处理重叠源和目的地的文本而memmove()
。
但是,当我在重叠的内存块上执行这两个函数时,它们都会给出相同的结果。例如,在memmove()
帮助页面上采用以下MSDN示例: -
有没有更好的例子来理解memcpy
的缺点以及memmove
如何解决它?
// crt_memcpy.c
// Illustrate overlapping copy: memmove always handles it correctly; memcpy may handle
// it correctly.
#include <memory.h>
#include <string.h>
#include <stdio.h>
char str1[7] = "aabbcc";
int main( void )
{
printf( "The string: %sn", str1 );
memcpy( str1 + 2, str1, 4 );
printf( "New string: %sn", str1 );
strcpy_s( str1, sizeof(str1), "aabbcc" ); // reset string
printf( "The string: %sn", str1 );
memmove( str1 + 2, str1, 4 );
printf( "New string: %sn", str1 );
}
输出:
The string: aabbcc
New string: aaaabb
The string: aabbcc
New string: aaaabb
没有找到相关结果
已邀请:
11 个回复
亲奋漏
复制到
,然后看看会发生什么。 (可能实际上没有区别,取决于编译器/库。) 通常,memcpy以简单(但快速)的方式实现。简单地说,它只是循环数据(按顺序),从一个位置复制到另一个位置。这可能导致源被读取时被覆盖。 Memmove做了更多工作以确保它正确处理重叠。 编辑: (不幸的是,我找不到像样的例子,但这些都可以)。对比此处显示的memcpy和memmove实现。 memcpy只是循环,而memmove执行测试以确定循环的方向以避免破坏数据。这些实现相当简单。大多数高性能实现都比较复杂(涉及一次复制字大小块而不是字节)。
闪脖
中的内存不能重叠,或者存在未定义行为的风险,而
中的内存可能会重叠。
memcpy的某些实现可能仍然适用于重叠输入,但您无法计算该行为。虽然memmove必须允许重叠。
仇聘发栖
不必处理重叠区域,并不意味着它不能正确处理它们。具有重叠区域的调用会产生未定义的行为。未定义的行为可以完全按照您在一个平台上的预期工作;这并不意味着它是正确或有效的。
掸牛浓疗
得到:
习让休堂溯
寄存器
在这里作为临时存储器使用,它“优雅地”修复了重叠问题。 复制6个字节时会出现这个缺点,至少是它的一部分。
输出:
看起来很奇怪,它也是由优化引起的。
这就是为什么我总是在尝试复制2个重叠的内存块时选择
。
括宠
和
之间的区别在于 在
中,指定大小的源内存被复制到缓冲区,然后移动到目标。因此,如果内存重叠,则没有副作用。 在
的情况下,源存储器没有额外的缓冲区。复制是直接在内存上完成的,这样当内存重叠时,我们会得到意想不到的结果。 这些可以通过以下代码观察到:
输出是:
邵酮
比
更复杂,因此它解释了内存重叠。 memmove的结果定义为将
复制到缓冲区然后将缓冲区复制到
。这并不意味着实际的实现使用任何缓冲区,但可能会做一些指针运算。
哭木算
此memcpy可以优化为:
悲帽慑彤电
输出:
但是你现在可以理解为什么memmove会处理重叠的问题。
藕挝
上的任何重叠都会导致未定义的行为,并且任何事情都可能发生:坏,无甚至好。好的很少见:-)
然而清楚地说,一切都像使用中间缓冲区一样,所以显然重叠是可以的。 但是,C ++
更宽容,并允许重叠:std :: copy是否处理重叠范围?
刷骸码
和
之间的明显区别。
不关心导致数据损坏的内存位置重叠,而
首先将数据复制到临时变量然后复制到实际内存位置。 在尝试将数据从位置
复制到
时,
的输出为“
”。问题是如何?
将从左到右一次复制一个字节。如你的程序“
”所示 所有复制将发生如下,
首先将数据复制到临时变量,然后复制到实际的存储位置。
输出是
:
: