-2
memcpy(buf, buf + (pos - offset), len);

whereas,

0<=pos<=strlen(buf), 0<=offset<=strlen(buf)

Is it safe to use memcpy() in this scenario? If not, what could go wrong? Please suggest the best practice.

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
linvenuza
  • 119
  • 8

2 Answers2

8

No it isn't. Use memmove instead.

If the memory zones overlap when using memcpy, the behaviour is undefined. Though it may appear to work depending on the implementation.

References:

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
2

Since C99, memcpy has the following declaration

void* memcpy(void *restrict dest, const void *restrict src, size_t count);

The restrict is a keyword that tells the compiler that the object of the pointer will only be accessed through the pointer itself. Essentially that means that the compiler (and the implementor of memcpy) can assume the two regions do not overlap.

So for example, if memcpy is implemented by a simple iteration copying bytes from the beginning, everything will be fine, as long as the regions do not overlap, and in fact it will be fine if the source region is above the destination region. However, if the regions overlap and the source region is at lower addresses than the destination region, the end of the source region will be clobbered by the copy before it is copied. This is possible in your case if pos - offset < 0 and offset - pos < len

You also can't assume that is the only possibility for error, some computer architectures have instructions that might make it quicker to start copying from the top and work downwards in which case memcpy is safe when the source is below the destination and overlapping, but not above the destination and overlapping. This would be true in your case if len > pos - offset

So with any possibility of overlap, always use memmove. You are however safe if len <= pos - offset because your two regions are guaranteed not to overlap.

JeremyP
  • 84,577
  • 15
  • 123
  • 161