我想了解的区别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: %s\n", str1 );
memcpy( str1 + 2, str1, 4 );
printf( "New string: %s\n", str1 );
strcpy_s( str1, sizeof(str1), "aabbcc" ); // reset string
printf( "The string: …Run Code Online (Sandbox Code Playgroud) 当我无法移动/复制memmove()/ memcpy()作为边缘情况时,我是否需要处理案例
int numberOfBytes = ...
if( numberOfBytes != 0 ) {
memmove( dest, source, numberOfBytes );
}
Run Code Online (Sandbox Code Playgroud)
或者我应该在没有检查的情况下调用该函数
int numberOfBytes = ...
memmove( dest, source, numberOfBytes );
Run Code Online (Sandbox Code Playgroud)
是否需要检查前片段?
该函数memmove定义如下:
void *memmove(void *dest, const void *src, size_t n);
Run Code Online (Sandbox Code Playgroud)
在Linux手册页中,它说:
返回值
memmove()函数返回指向dest的指针.
为什么函数只是定义为void memmove(…)总是返回其中一个输入参数?返回值可以与dest?不同?
或者返回值是否总是dest如此,只是能够以某种创造性的方式组合功能?
memcpy()和源之间的关键区别memmove()是,memmove()当源和目标重叠时,它将正常工作.当缓冲区肯定不重叠时,memcpy()更可取,因为它可能更快.
困扰我的是这个潜在的.它是一种微观优化还是存在真正重要的例子,当memcpy()我们真的需要使用memcpy()而不是坚持memmove()到处时?
memmove()函数将n个字节从内存区域src复制到内存区域dest.存储区可能重叠:复制的过程就好像src中的字节首先被复制到一个不与src或dest重叠的临时数组中,然后将字节从临时数组复制到dest.
我们可以只执行以下操作,而不是分配临时数组并复制值两次:
void *my_memmove(void *dest, const void *src, size_t n) {
signed char operation;
size_t end;
size_t current;
if(dest != src) {
if(dest < src) {
operation = 1;
current = 0;
end = n;
} else {
operation = -1;
current = n - 1;
end = -1;
}
for( ; current != end; current += operation) {
*(((unsigned char*)dest) + current) = *(((unsigned char*)src) + current);
}
}
return dest;
}
Run Code Online (Sandbox Code Playgroud)
在这个实现中,我们只是处理我们开始复制的位置.
我的实施有缺点吗?
注意:我实际上不会使用我的实现.我只是好奇.
我对使用memmove()有两个疑问:
我希望我能以一种好的方式解释我的怀疑.
编辑:我必须从数组中删除一个元素,然后我想在左侧移动已删除的元素的以下元素.
memmove/memcpy/strcpy原型中的第二个arg是类似的:例如:
void *memmove(void *dest, const void *src, size_t n); //const void*
char *strcpy(char *dest, const char *src); //const char*
Run Code Online (Sandbox Code Playgroud)
但显然,如果dest和src重叠,那么src的内容会被改变,违反const void/char*?
正如在这个问题的答案中指出的那样,编译器(在这种情况下是gcc-4.1.2,是的,它是旧的,我不能改变它)可以用它认为合适的memcpy替换结构赋值.
我正在valgrind下运行一些代码,并收到有关memcpy源/目标重叠的警告.当我查看代码时,我看到了这一点(释义):
struct outer
{
struct inner i;
// lots of other stuff
};
struct inner
{
int x;
// lots of other stuff
};
void frob(struct inner* i, struct outer* o)
{
o->i = *i;
}
int main()
{
struct outer o;
// assign a bunch of fields in o->i...
frob(&o.i, o);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
如果gcc决定用该替换该赋值memcpy,那么它是一个无效的调用,因为源和dest重叠.
显然,如果我改变赋值语句frob来调用memmove,那么问题就会消失.
但这是一个编译器错误,还是该赋值语句以某种方式无效?
在阅读有关memmove的内容时,我读到它可以处理MEMORY OVERLAPS,但我无法知道两个字符串之间如何发生内存重叠,以及该函数如何仍能正确复制内存块.