可以吗?memcpy部分复制
char buf[] = { 0, 1, 2 };
memcpy(buf, buf + 1, 2);
是否有更大的数据类型有什么区别?我知道我可以使用memmove(),但我只是好奇。
可以吗?memcpy部分复制
char buf[] = { 0, 1, 2 };
memcpy(buf, buf + 1, 2);
是否有更大的数据类型有什么区别?我知道我可以使用memmove(),但我只是好奇。
当输入和输出重叠时,memcpy
的效果未定义。你应该使用memmove
。
不好。当源和目标重叠时,您必须必须使用memmove
。
它可能使用memcpy
,这取决于你的编译器的实现,但这不是你应该依赖的东西!
一个典型的幼稚的做法是逐字节副本(UINT8)是这样的:
typedef unsigned char uint8;
void * memcpy (void * destination, const void * source, size_t num)
{
const uint8* pSrc = (const uint8*)source;
const uint8* const pSrcEnd = pSrc + num;
uint8* pDst = (uint8*)destination;
while (pSrc != pSrcEnd)
*(pDst++) = *(pSrc++);
return destination;
}
这将工作没关系你memcpy(buf, buf + 1, 2)
,但少为人与memcpy(buf + 1, buf, 2)
如果内存区域重叠,行为是不确定的,所以这是不好的。
这是不确定的行为,但我已经用它像这样,
char buf[] = {0, 1, 2, 3);
memcpy(buf, buf+2, 2);
在目的地的终点是小于源的起点。 你应该仍然使用memmove来确保...
GNU C库已经转换了几次memcpy的实现。有时甚至i686与i386与x86_64不同。 – 2012-04-11 22:19:28
-1:当你尝试时发生了什么? – pmg 2011-03-15 12:03:17
+1,因为我不同意pmg的-1。 “当你在标准中查看时发生了什么?”,也许,但是在尝试这种事情时存在真正的风险,你可能会尝试并且“有效”,结果为{1,2,2} '在缓冲区中。那么建议有什么用处呢?它是否会在下周仍然有效,或者当您打开优化或客户计算机时仍然有效? – 2011-03-15 12:37:49
@Steve Jessop:我同意。 OP的例子将(可能)工作,这取决于'memcpy'的特定目标平台实现,但这并不是一个好主意! – GrahamS 2011-03-15 12:42:00