Question

Is it safe to use memcpy in the following scenario, where one is copying data from larger index into a block to smaller index in the same block. For example:

char buf[100];
// fill in the data ...
memcpy(&buf[10], &buf[15], 10);

In the above scenario I don't care about data from location 10 - 19 and am fine if its overwritten. Is there some reason why this should be avoided and memmove used instead?

EDIT: Sorry I have not communicated my intention properly, so lets say I have data from index 10 - 19 and data from index 15 - 24, I want to copy data from 15 - 24 over 10 - 19, and I don't care about data from 10 - 19, is it safe to us memcpy even though they are overlapping?

Was it helpful?

Solution

Edit:

Based on your edit, invert the following answer, since now you don't agree with the restrict constraints.


Old answer

Yes it is safe. You are copying buf[10] through buf[19] on buf[20] through buf[29]. (Note that the first parameter of memcpy is destination. So buf[10] through buf[19] are not being overwritten.)

memcpy is defined in C11 as:

void *memcpy(void * restrict s1, const void * restrict s2, size_t n);

notice the restrict keyword. C11 at 6.7.3.8 says (emphasis mine):

An object that is accessed through a restrict-qualified pointer has a special association with that pointer. This association, defined in 6.7.3.1 below, requires that all accesses to that object use, directly or indirectly, the value of that particular pointer.135) The intended use of the restrict qualifier (like the register storage class) is to promote optimization, and deleting all instances of the qualifier from all preprocessing translation units composing a conforming program does not change its meaning (i.e., observable behavior).

In your example, buf[10] through buf[19] are accessed only through the s2 pointer and buf[20] through buf[29] are accessed only through the s1 pointer. Therefore, your usage of memcpy is perfectly ok.

In simpler terms, as long as the arrays you give to memcpy don't overlap, it's ok.

OTHER TIPS

As you specified in the statment:

memcpy(&buf[20], &buf[10], 10);

The data from the index 10 to 19 doesnt overlap with the data from the index 20 to 29 so it's secure to use memcpy() even if you care about the data from the index 10 to 19.

Note that if the data overlaps even if you don't care about the data you're copying it's not safe to use memcpy since the direction in which memcpy is copying is not specified

It is safe. There is no reason to use memmove.

memcpy doens't specify a direction so memcpy(&buf[20], &buf[10], 20); would be confusing. we have to make surethe copy starts at &buf[20]. memmove and std::copy do make such guarantees, so they could be safely used in such a case.

memcpy(&buf[10], &buf[20], 10); doens't overlap because &buf[10] + 9 == &buf[19] is the make address copied to and is less than &buf[20].

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top