I've got a String
class with a char* buffer
and a unsigned int length
.
The string class has two constructors:
String(const char* str);
String(const String& other);
and a destructor
~String()
which deletes the char array with delete[] buffer;
.
Both constructors create a new buffer array buffer = new char[size];
and fill it with the correct data from either the const char* string
or the const String& other
. The string buffer is null-terminated.
In my main function I've got the following code:
int main() {
String a("Hello");
a = a.Replace('l', 'p');
printf("%s\n", a.char_ptr());
}
I would expect it to print Heppo
to the console. The replace
function takes two characters where all occurrences of the first one are replaced by the second one. It returns an entirely new String
:
String String::Replace(const char& a, const char& b) {
const char* buf = ...;
// Do the replacement and store the result in buf
String s(buf);
delete[] buf;
return s;
}
From my understanding, the compiler will return a copy of the local variable s
. Because of that, the a
variable in main()
should be a perfectly legitimate String
. But the output to the console looks like ¦¦¦¦¦¦¦¦¦¦
, which looks like uninitialized memory.
Even weirder, when i change my main method to:
int main() {
String a("Hello");
String b = a.Replace('l', 'p');
printf("%s\n", b.char_ptr());
}
I see the expected output. After a lot of reading I could not figure out the solution, as this is problem is really hard to describe in a google/stackoverflow search.
the main problem is violation of the rule of big 3. since you have a none trivial destructur, you must also define a copy constructor and an assignment operator. you may consider the copy-swap idiom in implementing the above functions. Not definining either of the two in presence of a none-trivial destructor, leads to resource(memory in this sample) leak.