-1

在以下场景中使用是否安全memcpy,其中将数据从较大的索引复制到一个块到同一块中的较小索引。例如:

char buf[100];
// fill in the data ...
memcpy(&buf[10], &buf[15], 10);

在上述情况下,我不关心来自位置 10 - 19 的数据,如果它被覆盖就可以了。有什么理由应该避免和memmove使用它吗?

编辑:对不起,我没有正确传达我的意图,所以假设我有来自索引 10 - 19 的数据和来自索引 15 - 24 的数据,我想从 15 - 24 复制 10 - 19 的数据,我不在乎关于 10 到 19 的数据,memcpy即使它们重叠,对我们来说安全吗?

4

3 回答 3

1

正如您在声明中指定的:

memcpy(&buf[20], &buf[10], 10);

索引到的数据不会与索引1019的数据重叠,20因此即使您关心索引到的数据也29可以安全使用。memcpy()1019

请注意,如果数据重叠,即使您不关心要复制的数据,使用也不安全,memcpy因为memcpy未指定复制方向

于 2014-01-18T13:49:49.090 回答
1

编辑:

根据您的编辑,反转以下答案,因为现在您不同意这些restrict约束。


旧答案

是的,它是安全的。您正在buf[10]通过复制。(请注意,第一个参数是目的地。所以through不会被覆盖。)buf[19]buf[20]buf[29]memcpybuf[10]buf[19]

memcpy在 C11 中定义为:

void *memcpy(void * restrict s1, const void * restrict s2, size_t n);

注意restrict关键字。C11 在 6.7.3.8 说(强调我的):

通过限制限定指针访问的对象与该指针具有特殊关联。这种关联,在下面的 6.7.3.1 中定义,要求对该对象的所有访问直接或间接使用该特定指针的值。135) 限制限定符的预期用途(如寄存器存储类)是为了促进优化,并且从构成符合程序的所有预处理翻译单元中删除限定符的所有实例不会改变其含义(即,可观察的行为)。

在您的示例中,buf[10]通过buf[19]仅通过s2指针访问,buf[20]通过仅通过指针buf[29]访问s1。因此,您的使用memcpy完全没问题。

简单来说,只要你给的数组memcpy不重叠,就可以了。

于 2014-01-18T13:50:51.037 回答
0

这是安全的。没有理由使用memmove.

memcpy没有指定方向,所以memcpy(&buf[20], &buf[10], 20);会令人困惑。我们必须确保副本从&buf[20]. memmovestd::copy做出这样的保证,以便在这种情况下可以安全地使用它们。

memcpy(&buf[10], &buf[20], 10);不重叠,因为&buf[10] + 9 == &buf[19]生成地址被复制到并且小于&buf[20].

于 2014-01-18T13:48:47.940 回答