PaulS:
Well, there was one thing. Instead of allocating memory again for every single character being added, most String classes allocate more memory is somewhat larger chunks. Allocating memory to hold the current data plus 10 characters, when the previous allocation was filled, would reduce the number of times malloc(), memcpy(), and free() need to be used.The tradeoff is that the number of unused elements at the end needs to be managed, but that is not a big deal.
This is not to say that I think the String class is a good idea. I do not. But, there are things that it could do better.
That would reduce the number of malloc/free calls, at the expense of, on average, more wasted memory for each String object. You'd STILL, at some point, end up with fragmented memory, or just plain run out of memory, if you do a lot of random String operations. It may happen later, it may happen sooner, depending on the specific usage pattern. End of the day, you haven't actually "fixed" anything, you've simply changed when/where/how it will eventually fail, and for at least some applications you will have made it worse.
Regards,
Ray L.