In an interview, I was asked to write an implementation of strcpy and then fix it so that it properly handles overlapping strings. My implementation is below and it is very naiv
Even without using relational pointer comparisons, memmove
, or equivalent, it is possible to code a version of strcpy
which will be performed as an strlen
and memcpy
in the non-overlapping case, and as a top-down copy in the overlapping case. The key is to exploit the fact that if the first byte of the destination is read and then replaced with zero, calling strlen
on the source and adding to the source pointer the value that was returned will yield a legitimate pointer which will equal the start of the destination in the "troublesome overlap" case. If the source and destination are different objects, the "source plus strlen" pointer may be safely computed and observed to be unequal to the destination.
In the event that adding the string length to the source pointer yields the destination pointer, replacing the zero byte with the earlier-read value and calling strlen on the destination will allow code to determine the ending address of the source and destination strings. Further, the length of the source string will indicate the distance between the pointers. If this value is large (probably greater than 16 or so), code may efficiently subdivide the "move" operation into a top-down sequence of memcpy operations. Otherwise the string may be copied with a top-down loop of single-byte copy operations, or with a sequence of "memcpy to source to buffer"/"memcpy buffer to destination" operations [if the per-byte cost of a large memcpy is less than half that of an individual-character-copy loop, using a ~256-byte buffer may be a useful optimization].