18

来自memmove(3)的 Linux 手册页

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;
}

在这个实现中,我们只需要处理我们开始复制的位置。

我的实施有缺点吗?

注意:我实际上不会使用我的实现。我只是好奇。

4

1 回答 1

38

您可以在此处此处此处此处查看 memmove 的一些源代码。

你会注意到他们实际上并没有创建一个临时数组。编写手册页是为了帮助您理解它在逻辑上而不是实际上在做什么。因此,他们说“好像”。

memmove() 实际上所做的是将字节从srcto复制dest,并且它向前复制 if dest < src(这与 memcpy 基本相同),否则向后复制。

memcpy和之间的区别在于memmove盲目memcpy地向前复制——这就是为什么dest也不src应该重叠。但memmove要注意确保重叠不会搞砸最终结果。

于 2012-11-12T07:39:30.507 回答