As with C++'s std::string, the Arduino String has several advantages:
- It can handle strings with embedded
NUL bytes ('\0')
- Computing the length is constant time (it's a stored value, not derived by scanning for a
NUL from the beginning)
- It uses an overallocation strategy so repeated in-place concatenation is cheaper; rather than allocating exactly what it needs for the concatenation, it allocates a bit more (implementation dependent) so a bunch of small concatenations don't end up reallocating for every concatenation
- It manages a lot of allocation tasks for you as well, making it easier to avoid buffer overflows (where a plain char array is either fixed size, or you're manually managing dynamically allocated memory; either way, the risk of overflow or memory leaks goes up)
The main downsides are that the storage is always dynamically allocated (a stack local char array can reduce memory fragmentation and improve cache coherency), and that you're always storing the length and capacity of the String under the hood, so you're paying (depending on pointer size for the processor and precise guarantees of the type) 12-24 bytes of fixed overhead beyond what a plain stack array of char would involve; if you've got a lot of very small Strings and limited memory, that might hurt you bit (though for a lot of them, even with char arrays you're probably dynamically allocating, so you'd still pay the pointer and allocator overhead, just not the length and capacity overhead).
Essentially, you use String for the same reasons you use std::string in normal C++.