【问题标题】:Using memcpy to copy part of an array, and other memory manipulation tools使用 memcpy 复制数组的一部分,以及其他内存操作工具
【发布时间】:2013-01-23 07:33:33
【问题描述】:

是否可以使用 memcpy 来复制数组的一部分?

例如,我们有一个由 10 个整数组成的数组。我们可以创建一个新数组,并将最后 5 个整数复制到其中吗?

是否有其他可用于 c/c++ 的内存/数组复制/操作工具?

【问题讨论】:

  • 在 C++ 中编写代码时,您几乎肯定希望使用 std::vector 而不是数组(除非您有充分的理由想要一个大小在编译时固定的容器,在这种情况下你应该使用std::array 而不是内置数组)。
  • 原始内存正是我为此目的所需要的:执行时间紧迫,必须快速。 std::vector 是不够的。 (或者至少我认为它会更慢。)
  • @EdwardBird:您认为它会更慢,但 vector 的性能可能会让您大吃一惊。至少在完全忽略 STL 之前执行计时指标。
  • std::vector 会尽可能快,前提是你使用得当。
  • 在尝试改进低级操作之前,请查看my favorite example 的编译器优化(我自己写的 :-)。编译器会为你做这件事。在我的示例中,10 行 C++ 模板代码变成了 4-5 条机器指令,并在纳秒内执行。

标签: c++ arrays memcpy


【解决方案1】:

是否可以使用 memcpy 来复制数组的一部分?

不,一般情况下是不可能的。只有当数组中元素的类型为 trivial 布局时,您才能这样做。

例如,我们有一个由 10 个整数组成的数组。我们可以创建一个新数组,并将最后 5 个整数复制到其中吗?

ints 是 trivial 类型,因此对于这种特殊情况,它会起作用:

int source[10] = { ::: };
int target[5];

std::memcpy( target, source + 5, 5 * sizeof(int) );

是否有其他可用于 c/c++ 的内存/数组复制/操作工具?

当然,C++ 标准库 中的整套算法都适用于数组。您使用指向数组中第一个和最后一个元素的指针作为begin/end 迭代器。或者,如果您使用的是 C++11,那么只需 std::begin|end( array )

std::copy( source + 5, source + 10, target + 0 );

std::copy( std::begin(source) + 5, std::end(source), std::begin(target) );

这是一个元函数,您可以使用它来检查一个类型是否平凡,以及此类概念的定义:http://en.cppreference.com/w/cpp/types/is_trivial

【讨论】:

  • @EdwardBird:是的——例如,不可能复制没有复制构造函数的对象。
  • @EdwardBird:是的,任何非琐碎的类型。这包括几乎所有不是普通旧 C 类型的类型。
  • @EdwardBird 它只保证适用于具有普通构造函数、普通析构函数、普通复制和移动构造函数以及普通复制和移动赋值运算符的类型。这意味着指针可以,但智能指针不行。
  • @EdwardBird:指针和数组都是纯 C 类型,所以是的。每个基本类型都是平凡的,平凡类型的聚合(数组或结构)也是平凡的。另一方面,std::stringstd::complex 并非微不足道。
  • 基本上,如果您编写自己的复制和赋值构造函数,它适用于所有事情?
【解决方案2】:

memmove() 用于此目的。

编辑:memcpy() 工作得很好。无论如何,它可能更精简。

在本例中,代码如下所示:

int array1[10] = {0,1,2,3,4,5,6,7,8,9};
int array2[5] = {0,0,0,0,0};

memmove(array2, array1 + 5 * sizeof(int), 5 * sizeof(int));

这将从array1的位置5复制5个int到array2的位置0。

【讨论】:

  • 这个答案没有意义。 memmovememcopy 相同,只是它正确处理重叠的源和目标内存范围。当可以使用 memcopy/memmove 复制数组的一部分时,答案没有解决。
  • 好的,那么在这种情况下 memcpy 就是答案。
  • memcpy 是个问题。这个答案没有说明可以使用 memcpy 复制哪些类型的数组。
  • array1 + 5 * sizeof(int)是一个远离&array1[5]的地方
  • 请解释而不是添加废话。
猜你喜欢
  • 2017-03-10
  • 1970-01-01
  • 2017-11-13
  • 1970-01-01
  • 1970-01-01
  • 2012-12-20
  • 2021-12-27
  • 1970-01-01
  • 2023-03-30
相关资源
最近更新 更多