Figure 1 Good objects must do their own memory management

class BadString {
public:
// Using the pointer directly:
  BadString(char *s) { ptr = s; }
// Where did pointer come from:
  ~BadString() { delete[] ptr; }
private:
  char *ptr;
};

char *strdup(const char *str)
{
  return strcpy(new
    char[strlen(str)+1],str);
}

class GoodString {
public:
// Don't use the pointer, copy it:
  GoodString(const char *s)
    { ptr= strdup(s); }
// Now you can safely delete it:
  ~GoodString()
    { delete[] ptr; }
private:
  char *ptr;
};

// End of File