Using size_t as the common solution seems like the way to go.
struct string { char *data; size_t size; size_t alloc_size; };
struct string_view { char *data; size_t size; };
And we have the same design that C++ uses.