8

Is it possible to use memcpy to copy part of an array?

Say for example we have an array of 10 integers. Can we create a new array, and copy the last 5 integers into it?

Are there other memory/array copying/manipulation tools which are available for use with c/c++?

FreelanceConsultant
  • 13,167
  • 27
  • 115
  • 225
  • You almost certainly want to use `std::vector` rather than arrays when writing code in C++ (unless you have a really good reason to want a container with a size that is fixed at compile time, in which case you should use `std::array` rather than built in arrays). – Mankarse Feb 07 '13 at 17:37
  • Raw memory is exactly what I need for this purpose: The execution is time critical and must be fast. std::vector will not suffice. (Or at least I assume it will be slower.) – FreelanceConsultant Feb 07 '13 at 17:39
  • You assume it will be slower, but vector's performance may surprise you. At least perform timing metrics before you discount the STL altogether. – AndyG Feb 07 '13 at 17:49
  • `std::vector` will be as fast as possible, assuming you use it right. – K-ballo Feb 07 '13 at 17:50
  • Please check out [my favorite example](http://stackoverflow.com/a/11639305/597607) of compiler optimizations (I wrote it myself :-) before you try to improve on low level operation. The compiler will do that for you. In my example, 10 lines of C++ template code turns into 4-5 machine instructions and executes in nanoseconds. – Bo Persson Feb 07 '13 at 18:55

2 Answers2

12

Is it possible to use memcpy to copy part of an array?

No, it is not possible in the general case. You can only do that when the type of the elements in the array is of trivial layout.

Say for example we have an array of 10 integers. Can we create a new array, and copy the last 5 integers into it?

ints are trivial types, so for that particular case it would work:

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

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

Are there other memory/array copying/manipulation tools which are available for use with c/c++?

Sure, the entire set of algorithms in C++ Standard Library will work with arrays. You use pointers to the first and one-past-the-last elements in the array as begin/end iterators. Or if you are using C++11 then just std::begin|end( array ).

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

or

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

Here is a metafunction you can use to check whether a type is trivial, along with the definition of such concept: http://en.cppreference.com/w/cpp/types/is_trivial

K-ballo
  • 80,396
  • 20
  • 159
  • 169
  • @EdwardBird: Yes -- for example, it is impossible to copy objects which do not have copy-constructors. – Mankarse Feb 07 '13 at 17:42
  • @EdwardBird: Yes, any type that is not _trivial_. That includes pretty much every type that is not a plain old C type. – K-ballo Feb 07 '13 at 17:43
  • @EdwardBird it is only guaranteed to work for types that have a trivial constructor, trivial destructor, trivial copy and move constructors and trivial copy and move assignment operators. That means pointers are okay, but smart pointers are not. – Dirk Holsopple Feb 07 '13 at 17:46
  • @EdwardBird: Pointers and arrays are both plain C types, so yes. Every fundamental type is trivial, and an aggregate (array or struct) of trivial types is trivial as well. `std::string` and `std::complex` on the other hand are not trivial. – K-ballo Feb 07 '13 at 17:48
  • Basically, it will work for everything if you write your own constructors for copy and assignment? – FreelanceConsultant Feb 07 '13 at 18:00
  • @EdwardBird: No, it won't work for anything with a constructor and/or copy-assignment, either explicit or implicit, that is not trivial. – K-ballo Feb 07 '13 at 18:05
  • What about an array of floats? Is there a list somewhere of which types are "trivial"? – Adjwilley May 11 '19 at 15:10
1

memmove() serves for this purpose.

EDIT: memcpy() works just fine. It is probably more streamline anyway.

In this example, the code would be something like this:

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

This will copy 5 lots of int from array1, position 5, to array2, position 0.

FreelanceConsultant
  • 13,167
  • 27
  • 115
  • 225