Thread: deleting variable

  1. #1
    Code Warrior
    Join Date
    Nov 2001
    Posts
    669

    Question deleting variable

    Hi!

    I'm a little confused about deleting a variable in this case:

    file String.hpp ...
    Code:
    ...
    class String {
      public:
    	String(const char *text);
    	~String();
    	...
      private:
    	void setString(const char *text);
    	void freeMem(void *mem);
    
    	char *text;
    };
    file String.cpp ...
    Code:
    # include ".\String.hpp"
    ...
    
    String::String() {
      text = new char('\0');
    }
    
    String::~String() {
      freeMem(text);
    }
    
    void String::freeMem(void *mem) {
      delete mem;
      mem = NULL;
    }
    
    void String::setString(const char *text) {
      // delete previously allocated memory
      freeMem(text);
    
      // allocate a new memory
      int len = (int)strlen(text);
      this->text = new char[len + 1];
      strncpy(this->text, text, len + 1);
    }
    ...
    Testing the String class
    file main.cpp ...
    Code:
    # include ".\String.hpp"
    
    int main() {
      char *myText = new char[21];
    
      strncpy(myText, "hello world!", 21);
      String s = myText;
      delete myText;	// IS THIS CORRECT?
      myText = NULL;  // if not, than where should I clear the memory?
      cout << s;
      return 0;
    }
    Otherwise, is this design good?
    Current projects:
    1) User Interface Development Kit (C++)
    2) HTML SDK (C++)
    3) Classes (C++)
    4) INI Editor (Delphi)

  2. #2
    Chief Code Coloniser!
    Join Date
    Apr 2005
    Posts
    121
    You don't need to do most of that. Testing it would be as simple as:
    Code:
    String s = "Hello world";
    cout << s;
    s = "Hello world 2!";
    cout << s;
    There is no need for the dynamic memory allocation/deletion of characters in the test program.

    As far as the design goes, there are plenty of things you could do to make it better and faster. if you're looking to make your own string class as practice for something, then perhaps try and implement one that supports the use of UNICODE characters as well as ANSI. You could do something smarter than deleting and reallocating every time you assign a value to the string.

    As a side note, this is what your freeMem function should look like:
    Code:
    void String::freeMem(void *mem) {
      delete [] mem;
      mem = NULL;
    }
    ... and your constructor should look like this:
    Code:
    String::String() {
      text = new char[1];
      text[0] = '\0';
    }
    Hope that helps!

  3. #3
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    You must match each new[] with a delete[]. Thus, every allocation in String should use new[], because otherwise you have to remember which you used.

    Using strncpy is not necessary in strcpy. It is only necessary if the input string might be longer than the destination, or might be missing a terminating NUL. Neither is the case here: if it was missing a NUL, strlen already read past its end. And since you use strlen, you're guaranteed to have sufficient space.

    Don't cast the return value of strlen. Rather, make len a size_t.

    There's no need in main to ever allocate this buffer. Just assign the string literal directly.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  4. #4
    Code Warrior
    Join Date
    Nov 2001
    Posts
    669
    Thanks for the reply.

    Can you give me an example for using UNICODE?
    Current projects:
    1) User Interface Development Kit (C++)
    2) HTML SDK (C++)
    3) Classes (C++)
    4) INI Editor (Delphi)

  5. #5
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Basically, you'd replace all occurences of char with wchar_t, all occurrences of strlen with wcslen etc. However, to make it work with both is trickier. You'd have to make your class a template on the character type. (This is how std::string works. It's a class template called basic_string, where string is a typedef for char and wstring one for wchar_t.) However, when you've done that, you can't use strlen and friends anymore, so you need a traits template that defines how to find the length of a nul-terminated sequence of that type and similar things. (std::string uses std::char_traits. You can just reuse the interface.) That traits type would be the second template parameter and should have some default. (std::char_traits, for example.)
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  6. #6
    Registered User
    Join Date
    Apr 2002
    Posts
    1,571
    Actually, your freeMem function should look like this:

    Code:
    void String::freeMem(void *&mem) {
      delete [] mem;
      mem = NULL;
    }
    "...the results are undefined, and we all know what "undefined" means: it means it works during development, it works during testing, and it blows up in your most important customers' faces." --Scott Meyers

  7. #7
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Actually, it should take no parameter at all and work directly on the text member. Nice catch, though.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

  8. #8
    Code Warrior
    Join Date
    Nov 2001
    Posts
    669
    What does this mean "void *&mem"? What's the trick?
    Current projects:
    1) User Interface Development Kit (C++)
    2) HTML SDK (C++)
    3) Classes (C++)
    4) INI Editor (Delphi)

  9. #9
    Cat without Hat CornedBee's Avatar
    Join Date
    Apr 2003
    Posts
    8,895
    Well, the problem is that in freeMem, you set to NULL a local copy of the pointer. So, while you actually free the memory pointed to, the "text" member of the class still points to that - now invalid - memory.
    MrWizard's weird syntax means that a reference to the pointer will be passed, not a copy of it. Thus, when you set it NULL, the actual "text" member will be set to NULL.

    I say it's better to remove the parameter altogether and act directly on the "text" member.
    All the buzzt!
    CornedBee

    "There is not now, nor has there ever been, nor will there ever be, any programming language in which it is the least bit difficult to write bad code."
    - Flon's Law

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. deleting and re-assigning a global variable pointer
    By Canadian0469 in forum C++ Programming
    Replies: 2
    Last Post: 12-20-2008, 03:47 PM
  2. variable being reset
    By FoodDude in forum C++ Programming
    Replies: 1
    Last Post: 09-15-2005, 12:30 PM
  3. float/double variable storage and precision
    By cjschw in forum C++ Programming
    Replies: 4
    Last Post: 07-28-2003, 06:23 PM
  4. Beginner question
    By Tride in forum C Programming
    Replies: 30
    Last Post: 05-24-2003, 08:36 AM
  5. static variable
    By Roaring_Tiger in forum C Programming
    Replies: 9
    Last Post: 04-01-2003, 01:12 PM