C++ FAQ Celebrating Twenty-One Years of the C++ FAQ!!!
(Click here for a personal note from Marshall Cline.)
Section 17:
[17.11] How do I change the string-length of an array of char to prevent memory leaks even if/when someone throws an exception?

If what you really want to do is work with strings, don't use an array of char in the first place, since arrays are evil. Instead use an object of some string-like class.

For example, suppose you want to get a copy of a string, fiddle with the copy, then append another string to the end of the fiddled copy. The array-of-char approach would look something like this:

void userCode(char const* s1, char const* s2)
{
  char* copy = new char[strlen(s1) + 1];    // make a copy
  strcpy(copy, s1);                         //   of s1...

  // use a try block to prevent memory leaks if we get an exception
  // note: we need the try block because we used a "dumb" char* above
  try {

    ...code that fiddles with copy...

    char* copy2 = new char[strlen(copy) + strlen(s2) + 1];  // append s2
    strcpy(copy2, copy);                                    //   onto the
    strcpy(copy2 + strlen(copy), s2);                       //     end of
    delete[] copy;                                          //       copy...
    copy = copy2;

    ...code that fiddles with copy again...

  }
  catch (...) {
    delete[] copy;   // we got an exception; prevent a memory leak
    throw;           // re-throw the current exception
  }

  delete[] copy;     // we did not get an exception; prevent a memory leak
}
Using char*s like this is tedious and error prone. Why not just use an object of some string class? Your compiler probably supplies a string-like class, and it's probably just as fast and certainly it's a lot simpler and safer than the char* code that you would have to write yourself. For example, if you're using the std::string class from the standardization committee, your code might look something like this:
#include <string>           // Let the compiler see std::string

void userCode(std::string const& s1, std::string const& s2)
{
  std::string copy = s1;    // make a copy of s1
  ...code that fiddles with copy...
  copy += s2;               // append s2 onto the end of copy
  ...code that fiddles with copy again...
}
The char* version requires you to write around three times more code than you would have to write with the std::string version. Most of the savings came from std::string's automatic memory management: in the std::string version, we didn't need to write any code...
  • to reallocate memory when we grow the string.
  • to delete[] anything at the end of the function.
  • to catch and re-throw any exceptions.