1

When moving strings between buffers, I frequently treat char* as data buffers, and use none of the string buffer (strncpy, strncat, etc). Example:

memcpy(target, src, strlen(src) + 1) // after buffer size checks
//vs
strncpy(target, src, target_size - 1);
target[target_size - 1] = 0;

Is this a bad practice?

EDIT: I know the difference, this is not a duplicate, but rather a question of standard practice.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
JavaProphet
  • 931
  • 14
  • 29
  • Assuming that you grant that `target` size is at least strlen(src) + 1 bytes longs, there's no harm in doing that. – pah Jul 07 '16 at 21:05
  • 1
    If you know the lengths of the strings, then `memmove()` or `memcpy()` is good practice — albeit not as often used as it could/should be. If you don't know the lengths of the strings, the `str*()` routines are frequently a disaster, and `strncat()` _is_ worse than `strncpy()`, but not by a large margin. – Jonathan Leffler Jul 07 '16 at 21:06
  • `memcpy()` will write `strlen(src) + 1` characters. `strncpy(target, src, target_size - 1); target[target_size - 1] = 0;` will write `target_size` characters. Important should the string length be large like a 1024 buffer for a copy of `"abc"`. – chux - Reinstate Monica Jul 07 '16 at 21:06
  • 1
    @JonathanLeffler: In what sense is `strncat` worse than `strncpy`? (BTW, [here's my rant on the topic](https://the-flat-trantor-society.blogspot.com/2012/03/no-strncpy-is-not-safer-strcpy.html).) – Keith Thompson Jul 07 '16 at 21:07
  • Possible duplicate of [Difference between strncpy and memcpy?](http://stackoverflow.com/questions/4593907/difference-between-strncpy-and-memcpy) – Mattia F. Jul 07 '16 at 21:09
  • @KeithThompson: What's the length argument argument for `strncat()`? Hint: it isn't the length of the target array. That's the problem with `strncat()`! It has different semantics for its length argument from everything else. —— For those who aren't sure (not Keith, I believe), the length for `strncat()` is the number of characters available after the string that's currently in the target buffer, and not the raw length of the target buffer as in `strncpy()` and `memmove()` and `memcpy()` and … – Jonathan Leffler Jul 07 '16 at 21:10
  • What is not clear from the code is its lack of context. "after buffer size checks" implies `strcpy(target, src);` is the best approach. OTOH, is the length was known prior then `memcpy(target, src, length+1)` makes sense. `strncpy(target, src, target_size - 1);` merits consideration if code lacks prior "buffer size checks", yet then error handling concerns are left unanswered. IMO - post lacks context for a good answer. – chux - Reinstate Monica Jul 07 '16 at 21:22

2 Answers2

3

Use of

memcpy(target, src, strlen(src) + 1) // after buffer size checks

potentially involves traversing the string twice -- once in strlen and once in memcpy. You take a small performance hit that you don't if you use strcpy.

If you compute the length of the string for unrelated reasons or have the length of the string from other resources, it's unclear to me whether memcpy is better or worse than strncpy.

If you don't the compute the length of the string for other reasons or don't have the length of the string from other resources, it is better to use strcpy instead of memcpy or strncpy.

R Sahu
  • 204,454
  • 14
  • 159
  • 270
2

If you know the semantics and sizes, it's not an issue. Remember that strncpy will stop at the first null and also fill the following bytes in the destination up to n characters with null bytes if the string is shorter (it will not write a null byte if there wasn't one in the source). strncpy can also give you a little bit of better typechecking, as it expects a char * in all cases, rather than a void *.

Which is more efficient is up for debate, but based on CPU bulk instructions which can copy an entire block of memory in one instruction, memcpy is probably faster, as strncpy would check each copied byte for a NUL character.

Taywee
  • 1,313
  • 11
  • 17
  • 1
    "strncpy will stop at the first null," --> no. It does more than that. It zero fills the target base on size. – chux - Reinstate Monica Jul 07 '16 at 21:10
  • You're right: `If the length of src is less than n, strncpy() writes additional null bytes to dest to ensure that a total of n bytes are written.` – Taywee Jul 07 '16 at 21:12
  • `memcpy()` can be much faster because it does not need to write the size of the destination buffer, like `strncpy()`, only up to the string length. With small string/buffers who cares, but with large buffers and strings of various lengths that savings can be significant. – chux - Reinstate Monica Jul 07 '16 at 21:25