When dealing with char arrays, you either have to settle for fixed-size arrays (limiting your string length), or else you need to use dynamic allocation (new/delete or malloc/free) to make sure you always have a big enough array.

For numerous reasons, getting dynamic allocation "right" in complex cases is nontrivial. Even experts can screw it up---don't allocate enough space and have a buffer overrun, forget to allocate a new array in a class's copy constructor, or simply fail to delete an array and end up with a memory leak. It's a pain.

std::string wraps all that difficult logic up in a clean, easy-to-use container that it's hard to screw up with.