You'd be surprised how far large static buffers and snprintf will get you. Easy to deal with, no leaks, valgrind is happy...
You got me thinking about ways one could get strdup wrong:
- input is not a string -> possible UB
- input is a string, but the character encoding wasn't what you thought -> possible UB
- input is a string, but it was the pointer-plus-length kind -> possible UB
- input is modified by another thread -> possible UB
- strdup called from within a signal handler -> possible UB
- failure to handle error return values -> possible UB
- failure to free the memory when it's no longer needed -> memory leak
- freed the memory more than once -> possible UB
- used the memory after freeing it -> possible UB
I've personally seen several of these in real-world code.
For example you could implement a string class in C++ using strlen, strdup etc. if you were feeling insane and it would probably be fine since you only use strdup once and then all the users of you class don't have to worry about getting it wrong.
If you write in C you have to use strdup every time you copy a string and there's no way you get it right 1000 times.