OS: Ubuntu Linux 9.4
GCC: v4.4.1
I'm writing a String class while learning about operator overloading. I'm having trouble with how to use overloaded binary operators in chained expressions. In this case, I have a String class whose private data members are
char *str
and
int length
. I wrote an overloaded + operator like this that employs a conversion constructor specifying member length:
1 2 3 4 5 6 7 8
|
String String::operator+( const String &s )
{
String temp( length + s.length );
strcpy( temp.str, str );
strcat( temp.str, s.str );
return temp;
}
|
In my driver program, I tried this test:
1 2 3 4
|
String str( "first," );
String str1( " second," );
str.operator+=((str1.operator+(" third,")).operator+(" fourth and final!"));
cout << "\nTesting String concatenation operator\n" << str.print() << "\n\n";
|
I wrote the operator statement using function notation just to see if I understand it properly, the resulting output is the same as using
str += str1 + " third" + " fourth and final!";
The output is (abridged):
1 2 3 4
|
Testing String concatenation operator
first, second, third fourth an1
*** glibc detected *** ./string: free(): invalid next size (fast): 0x00000000023340d0 ***
|
with a backtrace and memory map dump. The += operator doesn't appear to be the problem, I tried the driver operator statement using my overloaded assignment operator and had the same output. There seems to be a buffer overflow, so possibly my error lies in my not handling dynamic memory properly and resizing the
str
data.
My question is, am I approaching this the right way or is there some flaw in my understanding of how to build a chained statement like I attempted? I'm thinking this has something to do with my returning a String object by value from the operator+() function, and when a temporary local object is created in the statement and chained with the next part of the expression, it isn't resizing the str array.
I wanted to return a const reference from operator+(), but I couldn't see how to avoid a memory leak since the returned handle in the expression in question would cease to exist after the statement ended, and burdening the client code with deleting an object in this manner is bad design anyways. Help me clarify my thinking here!
If this helps, here's how I handled the operator+=() function.
1 2 3 4 5 6 7 8 9 10 11 12
|
void String::operator+=( const String &s )
{
length += s.length;
char *temp = new char[length + 1];
if( temp == 0 )
exit(1);
strcpy( temp, str );
strcat( temp, s.str );
delete [] str;
str = allocate( temp );
delete [] temp;
}
|