I do not think I have ever seen a string that needs more than 64K, but then again I do not read whole files in memory in C. (I do in Python.) So this would be wasteful in many cases.
My personal variant uses 32-bits for length and 32-bits for refcount, which aligns well on most platforms, including 64-bit ones.
Something like:
struct string_header
{
int32_t refcnt;
int32_t length;
// character content starts here
};
Given a char pointer to get to the header you must do: ((struct string_header *)p)[-1]