0

From the C Standard:

7.21.2.4 The strncpy function

If copying takes place between objects that overlap, the behavior is undefined.


What is overlapping?

It is clear that it is overlapping when the beginning of the destination string crosses the ending of the source string.

But is overlapping taking place in the next example?

const char* dateConst = "2017-01-25";
char* date = malloc(16);
strcpy(date, dateConst);

strncpy(date+4, date+5, 2);
strncpy(date+6, date+8, 3);

printf("%s\n", date);

Output: 20170125

If strncpy just copyes symbols char by char like it is in this implementation, there should be no problem.

Community
  • 1
  • 1
NuPagadi
  • 1,410
  • 1
  • 11
  • 31
  • 1
    While it is the C standard the dictates the behavior of `strncpy`, you seem to be compiling C++.. – StoryTeller - Unslander Monica Jan 25 '17 at 09:02
  • `strncpy` is a dangerous function and should be avoided. It was never intended to be used with null terminated strings to begin with. Instead, use `memcpy` or `strcpy`. – Lundin Jan 25 '17 at 10:10
  • @Lundin Wow, I've never heard that before. Why would you recommend `strcpy` over `strncpy`? (I've always heard the other way around.) – Leif Andersen Apr 20 '18 at 21:06
  • @LeifAndersen Because `strncpy` has a tendency to leave out the null terminator. It was never intended to be used for null-terminated strings in the first place, nor was it ever intended to be a "safe strcpy". [See this](https://stackoverflow.com/a/2115015/584518). As for `strcpy` being unsafe that's partially true, partially a myth created by Microsoft. As long as you know the size of the data to copy, it is perfectly safe. If you just copy an unknown string from an input buffer, with no error checking, well then obviously things will go wrong - no fault of strcpy. – Lundin Apr 23 '18 at 06:39

2 Answers2

1

strncpy doesn't have to be implemented in any specific way. The C standard only dictates the API contract it should follow. Any specific implementation may choose to make overlap a non-issue, but it isn't forced to do so by the standard.

strncpy can be implemented in terms of memcpy, which is subject to undefined behavior when the source and destination overlap. But with the specification mentioned above, it's perfectly okay.

StoryTeller - Unslander Monica
  • 165,132
  • 21
  • 377
  • 458
1

If strncpy just copyes symbols char by char like it is in this implementation, there should be no problem.

This is exactly the problem. The standard doesn't specify which way the function must operate, but what output should give, and, in the same time, specify that if there is any kind of overlap the result is UB making coders free to use whatever approach they like .

This is because new instructions or processor architectures could sponsor the use of new and more efficient instructions that could follow a different addressing way (i.e. copy in reverse order or in mixed order). This could give you whichever result not predictable, in fact an undefined behavior.

Eventually you can use memmove function that explicitly allows overlapping, or write your own function that is overlap aware.

Frankie_C
  • 4,764
  • 1
  • 13
  • 30