Do you understand what this code does?
What about this code?Code:delete[] buf; buf = new char[stringlength];
Code:return buf[i];
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
Why?I wanted to make a new buf array of size stringlength.
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).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&.
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.I did delete []buf because I wanted to avoid a memory leak. Is this wrong?
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
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.So should I delete the first two lines of the code and instead of return buf[i] should I return *this?
Incidentally:
should be:Code:buf[i] = ++buf[i];
Code:++buf[i];
Look up a C++ Reference and learn How To Ask Questions The Smart WayOriginally Posted by Bjarne Stroustrup (2000-10-14)
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]; } }
What is wrong with this code:
the debugger shows a break at this line of 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; }
Code:buf = new char[newsize];
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
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:
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.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); }
--
Mats
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; }
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
All problems in computer science can be solved by another level of indirection,
except for the problem of too many layers of indirection.
– David J. Wheeler