Why bother with memcpy?

Why use memcpy instead of type-specific copy functions, e.g. strncpy?

1
2
3
4
5
6
7
8
9
10
11
#include <stdio.h>
#include <string.h>

struct {
    char name[40];
    int age;
} person, person_copy;

int main ()
{
    char myname[] = "Pierre de Fermat";

At this juncture, either:

strncpy ( person.name, myname, strlen(myname));

or:

memcpy ( person.name, myname, strlen(myname)+1 );
Last edited on
The both statements you showed are incorrect (unsafe). The correct one will be

strncpy( person.name, myname, sizeof( person.name ) );
person.name[sizeof( person.name ) -1] = '\0';
Last edited on
Assuming this is a C question (in C++, you'd be using std::copy with arrays, and, come to think of it, you wouldn't be using arrays at all), the reason to prefer strncpy over memcpy with C strings is that memcpy expects to copy arrays of equal size, it literally copies x number of bytes, while strncpy can copy from a smaller C string to a larger destination array: it needs to know the size of the destination, it will figure out the size of the source on its own. It will also pad the destination with zeroes.
@Cubbi

Assuming this is a C question (in C++, you'd be using std::copy with arrays


I do not think that it is a good idea to use std::copy with character arrays instead of C standard string functions.:).
Last edited on
Oh, right, that's another reason: if you know the size of the source, std::copy/memcpy is more efficient than strncpy, since it doesn't have to look out for the zero.
person.name[sizeof( person.name ) -1] = '\0';

Vlad, why did you manually add the null character? (this is also addressed
to anyone else who might know the answer)
Last edited on
Vlad, why did you manually add the null character? (this is also addressed
to anyone else who might know the answer)


http://www.cplusplus.com/reference/cstring/strncpy/

Why ask for an answer you can look up yourself?
Usually character arrays store some string literals (though it is not necessary). If a source array is larger than a destination array then the terminating zero will not be copied and you can not for example use the destination array in some output operatioms as

std::cout << destination_array;

because these operations assume that the array has the terminating zero. Or you can not apply such string functions as strlen, strcpy and others to such an array without the terminating zero.
Last edited on
If a source array is larger than a destination array then the terminating zero will not be copied and you can not for example use the destination array in some output operations as

std::cout << destination_array;

because these operations assume that the array has the terminating zero. Or you can not apply such string functions as strlen, strcpy and others to such an array without the terminating zero.


I understand your instructions in the case that (1) the destination array is
the same size as the source; (2) the destination array is larger than the
source; but I do not understand them in the case that

(3) the destination array is smaller than the source.

1
2
3
4
5
6
7
8
9
struct name {
  char name[1];
  int age;
} John;

char myname[] = "John";

strncpy(John.name, myname, sizeof(John.name) );
John.name[sizeof(John.name) -1] = '\0';


You're assigning a null character to the one character copied. Thus, 'J'
is replaced with '\0'.
Yes. The result string will be empty because it can store only one symbol: terminating zero. If you want to copy more symbols then enlarge the destination array.
Damn, I should have seen that. Of course!
Topic archived. No new replies allowed.