String Class

This is a discussion on String Class within the C++ Programming forums, part of the General Programming Boards category; Originally Posted by laserlight Looks like it. Is this anywhere close to right? Code: String& String::operator ++() { delete []buf; ...

  1. #46
    Registered User
    Join Date
    Jul 2007
    Posts
    109
    Quote Originally Posted by laserlight View Post
    Looks like it.
    Is this anywhere close to right?

    Code:
    String& String::operator ++()
    {
    	delete []buf;
    	buf = new char[stringlength];
    	int i;
    	for(i = 0; i<stringlength; i++)
    		buf[i] = ++buf[i];
    	return buf[i];
    
    }

  2. #47
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,727
    Do you understand what this code does?
    Code:
    delete[] buf;
    buf = new char[stringlength];
    What about this code?
    Code:
    return buf[i];
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  3. #48
    Registered User
    Join Date
    Jul 2007
    Posts
    109
    Quote Originally Posted by laserlight View Post
    Do you understand what this code does?
    Code:
    delete[] buf;
    buf = new char[stringlength];
    What about this code?
    Code:
    return buf[i];
    I wanted to make a new buf array of size stringlength. buf[i] isn't what I should return? The problem with the code is that it gives an error that return can't convert from char to String&. I did delete []buf because I wanted to avoid a memory leak. Is this wrong?

  4. #49
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,727
    I wanted to make a new buf array of size stringlength.
    Why?

    buf[i] isn't what I should return? The problem with the code is that it gives an error that return can't convert from char to String&.
    Your function return type states that you want to return a reference to a String. What is the type of buf[i]? In fact, buf[i] is not a character in the string (it is a null character).

    I did delete []buf because I wanted to avoid a memory leak. Is this wrong?
    Pairing new[] with delete[] to avoid a memory leak is not wrong. What is wrong is that you want to add 1 to each character in the string but delete[] buf destroys the string, thus there is nothing to add to any more.
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #50
    Registered User
    Join Date
    Jul 2007
    Posts
    109
    Quote Originally Posted by laserlight View Post
    Why?


    Your function return type states that you want to return a reference to a String. What is the type of buf[i]? In fact, buf[i] is not a character in the string (it is a null character).


    Pairing new[] with delete[] to avoid a memory leak is not wrong. What is wrong is that you want to add 1 to each character in the string but delete[] buf destroys the string, thus there is nothing to add to any more.
    So should I delete the first two lines of the code and instead of return buf[i] should I return *this?

  6. #51
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    21,727
    So should I delete the first two lines of the code and instead of return buf[i] should I return *this?
    You are playing guess and check instead of programming logically here. Stop playing guess and check and start thinking. Once you have reasoned about your code, answer your own question.

    Incidentally:
    Code:
    buf[i] = ++buf[i];
    should be:
    Code:
    ++buf[i];
    C + C++ Compiler: MinGW port of GCC
    Version Control System: Bazaar

    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #52
    Registered User
    Join Date
    Jul 2007
    Posts
    109
    What is wrong with this constructor?
    Code:
    String::String(const char* str)
    { 
    	name = NULL;
        if (str==NULL)
        {
            stringlength = 0; 
            buf = new char[1];  
            buf[0]='\0';
        }
        else
        {
            size_t stringlen = strlen(str); 
            buf = new char[stringlen+1];
            for(int i=0; i <= stringlength; i++)
                buf[i] = str[i];
        }
    }

  8. #53
    Registered User
    Join Date
    Jul 2007
    Posts
    109
    What is wrong with this code:

    Code:
    const String& String::operator +=(const String & str)
    {
    	int newsize = getLength() + str.getLength() + 1;
    	char *temp = buf;
    	buf = new char[newsize];
    	assert(buf != 0);
    	strcpy(buf, temp);
    	strcat(buf, str.buf);
    	delete []temp;
    	return *this;
    }
    the debugger shows a break at this line of code.

    Code:
    buf = new char[newsize];

  9. #54
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by BKurosawa View Post
    What is wrong with this code:
    the debugger shows a break at this line of code.

    Code:
    buf = new char[newsize];
    Most likely is that you have overwritten the end of your buffer somewhere else, and when you end up in new the next time (or some number of times later), it fails because the "header" of the memory block that it's looking at is "broken".

    --
    Mats

  10. #55
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by BKurosawa View Post
    What is wrong with this constructor?
    Code:
    String::String(const char* str)
    { 
    	name = NULL;
        if (str==NULL)
        {
            stringlength = 0; 
            buf = new char[1];  
            buf[0]='\0';
        }
        else
        {
            size_t stringlen = strlen(str); 
            buf = new char[stringlen+1];
            for(int i=0; i <= stringlength; i++)
                buf[i] = str[i];
        }
    }
    I can't see anything directly wrong with it, but you are obviously of the opinion that it is broken in some way - so perhaps you could explain what makes you think there may be something wrong in there - or is this another "break at new" error? If so, it's most likely a delayed error from some other operation that failed.

    --
    Mats

  11. #56
    Registered User
    Join Date
    Jul 2007
    Posts
    109
    Quote Originally Posted by matsp View Post
    I can't see anything directly wrong with it, but you are obviously of the opinion that it is broken in some way - so perhaps you could explain what makes you think there may be something wrong in there - or is this another "break at new" error? If so, it's most likely a delayed error from some other operation that failed.

    --
    Mats
    I have already fixed that constructor. It now looks like:

    Code:
    String::String(const char *str)
    { 
    	name = NULL;
    	assert( str != 0);
    	stringlength = strlen(str);
    	buf = new char[stringlength + 1];
    	strcpy(buf, str);
    }

  12. #57
    Registered User
    Join Date
    Jul 2007
    Posts
    109
    Quote Originally Posted by matsp View Post
    Most likely is that you have overwritten the end of your buffer somewhere else, and when you end up in new the next time (or some number of times later), it fails because the "header" of the memory block that it's looking at is "broken".

    --
    Mats
    How can I find out where I overwrote the buffer or where the error is?

  13. #58
    Kernel hacker
    Join Date
    Jul 2007
    Location
    Farncombe, Surrey, England
    Posts
    15,677
    Quote Originally Posted by BKurosawa View Post
    How can I find out where I overwrote the buffer or where the error is?
    There are several ways, the most simple one (coding-wise) is to carefully check your code for "writing past the end".

    If on the other hand you want to check it "by machine", change your code so that whenever you do "new", you add some extra space, and fill that space with for example "0xAA". Add a macro at the beginning of every method to check that this "extra space" is still the 0xAA that you expect it to be.

    e.g:
    Code:
    #if DEBUG
    #define DEBUG_AREA 8
    #define DEBUG_PATTERN 0xAA
    #define CHECK_DEBUG(buf, len) check_debug(buf, len, __FILE__, __LINE__)
    #define FILL_DEBUG(buf, len) do { for(int _i = 0; _i < DEBUG_AREA; _i++) buf[len+i] = DEBUG_PATTERN; } while(0)
    
    void check_debug(char *buf, int len, const char *file, const int line) {
       int i;
       for(i = 0; i < DEBUG_AREA; i++) {
         if (buf[len+i] != 0xAA)
           break;
      }
      if (i != DEBUG_AREA) {
          cout << "ERROR: " << file << ":" << line << ": Buffer end overwritten" << endl;
          assert(0);
      }
    }
    #else
    #define DEBUGAREA 0
    #define DEBUG_PATTERN
    #define CHECK_DEBUG(buf, len)
    #define FILL_DEBUG(buf, len)
    #endif
    
    
    ....
    ....
    ....
    
    String::someFunction(...)
    {
       buf = new char[stringlength+1 + DEBUGAREA];
       FILL_DEBUG(buf, stringlength+1);
       ....
       .... 
       CHECK_DEBUG(buf, stringlength+1);
    }
    Another potential problem is if you use a pointer after it has been freed (deleted), that can have similar confusing effect on just about anything - that is harder to detect by adding code - although a strict regime of setting pointers to NULL after they have been freed can help find them sometimes.

    --
    Mats

  14. #59
    Registered User
    Join Date
    Jul 2007
    Posts
    109
    Why won't int newsize be initialized? See code below:

    Code:
    const String& String::operator +=(const String & str)
    {
    	int newsize = getLength() + str.getLength() + 1;
    	buf = new char[newsize];
    	char *temp = buf;
    	assert(buf != 0);
    	strcpy(buf, temp);
    	strcat(buf, str.buf);
    	delete []temp;
    	return *this;
    }
    
    int String::getLength()const
    {
    	return stringlength;
    }

  15. #60
    CSharpener vart's Avatar
    Join Date
    Oct 2006
    Location
    Rishon LeZion, Israel
    Posts
    6,484
    1. stringlength member may be not initialized or initialized not properly
    2. temp is pointing to the not initialized buffer buf
    3. strcpy(buf, temp); has no effect - you copying buffer over itself (maybe you think you copy the old buffer contents - but you effectively lost it making memory leak)
    4. strcat(buf, str.buf); - you appending to not initialized buffer - behavior is undefined
    5. delete []temp; - you deleting newly allocated buffer leaving your object in the dengerous state
    The first 90% of a project takes 90% of the time,
    the last 10% takes the other 90% of the time.

Page 4 of 8 FirstFirst 12345678 LastLast
Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  2. String issues
    By The_professor in forum C++ Programming
    Replies: 7
    Last Post: 06-12-2007, 09:11 AM
  3. We Got _DEBUG Errors
    By Tonto in forum Windows Programming
    Replies: 5
    Last Post: 12-22-2006, 04:45 PM
  4. class object manipulation
    By guda in forum C++ Programming
    Replies: 2
    Last Post: 10-09-2004, 10:43 AM
  5. Headers that use each other
    By nickname_changed in forum C++ Programming
    Replies: 7
    Last Post: 10-03-2003, 04:25 AM

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21