I am trying to learn C++ and was writing programs to learn Copy Constructors and Operator overloading. I am surprised that the below program when Copy constructor is used doesn't crash saying "Double Free", whereas when using Operator = overloading crashes consistently.
#include <iostream>
using namespace std;
class XHandler
{
public:
XHandler()
{
data = new char[8];
strcpy(data, "NoName");
}
XHandler (const char *str)
{
data = new char (strlen(str) + 1 );
strcpy (data, str);
}
XHandler (const XHandler &xh)
{
data = xh.data;
}
XHandler& operator = (const XHandler &xh)
{
data = xh.data;
}
~XHandler()
{
delete data;
}
void debug()
{
cout << data <<endl;
}
private:
char *data;
};
int main()
{
XHandler wm("hello"), wb("there");
wm.debug();
wb.debug();
XHandler wc (wm);
wc.debug();
XHandler wd;
wd = wc;
wd.debug();
}
Note that in both copy constructor and operator overloading, I am just copying the 'data' pointer from one object to another. When the destructor is invoked for 'wd' and 'wc', it crashes the program consistently. If I comment the below lines and execute only the copy constructor, the program doesn't crash at all. I would expect since both 'wc's and 'wm's data variable are also pointing to the same pointer, the program would crash.
XHandler wd;
wd = wc;
wd.debug();
I understand double delete is undefined behaviour. But, what I wonder is it consistently crashes in one way and doesn't in the other.
The behavior of "Undefined behavior" is just undefined. That means, no one put effort into that cases because that cases should not happen. Even a working program can be "Undefined behavior".
In your special case of an double delete, what happens, really depends on the implementation of the allocator. A usual implementation is to put released memory into a list and a next allocation will be satisfied with an element out of this list. If you double delete a chunk of memory, it will be added to the list twice. And then two allocation will be satisfied with the very same chunk of memory and thus two object will be created at the same memory location.
BTW: You destructor is already broken, as it doesn't use the array delete.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With