Re:Beware of strncpy and strncat
by beeforpork on Wednesday June 06, 2018 @01:47PM
(#17249324)
Same advice everywhere, very good, my words exactly: use snprintf().
But beware of old MS _snprintf:
https://docs.microsoft.com/en-us/previous-versions/visualstu...
Re:Beware of strncpy and strncat
by blattimwind on Wednesday June 06, 2018 @02:35PM
(#17249782)
> The advice given in this article is bad.
Thumbing through previous submissions of this domain with discussion, this seems to be a pattern.
Its a shame that many of the solution to those exist as non-standardized calls and seems split between BSD and GNU. Personally I use asprintf quite a lot, and I recall strndup to be quite useful to create a identical copy of a buffer. strndup should have an identical performance to allocating a buffer and then strlcpy, since it too do copy up to n-1 bytes and null-terminate.
It's a shame they aren't in ISO C, but strdup and strndup are at least standardized by POSIX: http://pubs.opengroup.org/onlinepubs/9699919799/functions/st...
Is there any reason not to use snprintf for almost every application of string manipulation (aside from strduping)?
Reason: performance.
If you just do string manipulation, memncpy is faster.
If you need to convert data type, like int to string, then use snprintf.
Yes, it seems I lied when I said sprintf is surprisingly fast. For most practical purposes it's fine, but if you need to do string manipulation in a hurry, strcpy/strlcpy are going to be faster.
See https://gist.github.com/nneonneo/f9dc5c1d1d342d25eae47d56dba... for a test harness. On my Mac, with a 16-byte string, 10 million loops:
memcpy: 77406 us
strlcpy: 101956 us
strncpy: 177247 us
sprintf: 730819 us
snprintf: 699844 us
memcpy smokes sprintf - around 10x faster. The vast majority of sprintf's time is spent in setup; for large strings, the gap closes substantially.Or use calloc. It does the same thing as malloc, but init memory to zero automatically.
If you’re going to allocate the memory you might as well just use the library functions that allocate exactly the space you need and copy the string into it. These tricks are for when you use the stack as an ‘optimization’.
strncpy sucks for a second reason: it writes n bytes no matter what the source is. That means if you write
this will fill 16K of memory with zeroes despite only needing to copy a 6-byte string.strlcpy/strlcat do the right thing (copy up to n-1 bytes and null-terminate); shame they aren’t standardized. In their absence, I suggest snprintf instead:
Because snprintf returns the number of bytes that would be written, it can be used to detect overlong input strings, reallocate the buffer as necessary, and also to implement efficient concatenation. It’s also surprisingly fast in most implementations.