为什么memcpy()无法复制同一数组中的数组元素但具有偏移量

我正在尝试将数组的内容复制到自身内部,但带有偏移量(或从偏移量)。例如:

int main(void) {
    char a[4] = { 'a', 'b' , 'c', 'd' }, b[4], c[4];

    memcpy(b, a, 4);
    memcpy(c, b, 4);

    memcpy(b, b + 1, 3);
    memcpy(c + 1, c, 3);

    for(unsigned i = 0; i < 4; i++)
        printf("%c", b[i]);
    printf("n");

    for(unsigned i = 0; i < 4; i++)
        printf("%c", c[i]);

    return 0;
}

给出以下输出:

bcdd
aaaa

我期待

bcdd
aabc

第一个memcpy它有效,但第二个在我看来它不是不一致的,所以我做错了。

我不明白我做错了什么。为什么会失败。另外,如果我尝试做同样的事情,但对于例如结构数组,这仍然会发生吗?

回答

2018 C 标准memcpy在条款 7.24.2.1 中进行了规定。第 2 段说:

… 如果复制发生在重叠的对象之间,则行为未定义。

要在数组内移动数据,请使用memmove. 它的规范,在 7.24.2.2 2 中说:

复制的发生就像首先将n指向的对象中的字符s2复制到与和n指向的对象不重叠的临时字符数组中,然后将临时数组中的字符复制到 指向的对象中。s1s2ns1

s1是目标,s2是源,n是要复制的字节数。)

  • @CătălinaSîrbu: The routine does not fail; its behavior conforms to its documentation. As for the reason it does not work the way you want, undoubtedly it is written, at least in part, as some simple loop like `for (int i = 0; i < n; ++i) s1[i] = s2[i];`. So `memcpy(c+1, c, 3)` is executed as `c[1] = c[0]; c[2] = c[1]; c[3] = c[2];`. In contrast, `memmove` must examine its pointers and decide whether to copy in the forward direction or the backward direction or even use some other method.

以上是为什么memcpy()无法复制同一数组中的数组元素但具有偏移量的全部内容。
THE END
分享
二维码
< <上一篇
下一篇>>