I created a test class to demonstrate the use of the overloaded assignment operator, and the pitfalls associated with double freeing memory. The code for this class is below:
class Test {
public:
Test() : ptr{new int(0)}, val{0}, id{count++} {}
Test(int ptr_val, int new_val) : ptr{new int(ptr_val)}, val{new_val}, id{count++} {}
~Test()
{
delete ptr;
}
Test& operator=(const Test& rhs)
{
*ptr = *(rhs.ptr);
val = rhs.val;
}
void setPtrVal(int ptr_val)
{
*ptr = ptr_val;
}
void setVal(int new_val)
{
val = new_val;
}
void printData() const
{
cout << "id = " << id << endl;
cout << "val = " << val << endl;
cout << "ptr = " << ptr << endl;
cout << "*ptr = " << *ptr << endl << endl;
}
private:
int* ptr;
int val;
int id;
static int count;
};
int Test::count = 1;
And I am having two main functions which are testing this class with the overloaded assignment operator. I am putting the output for each main function directly below it's body.
Main 1:
int main()
{
Test t1;
Test t2(2, 2);
t1.printData();
t2.printData();
t2 = t1; // Overloaded Assignment Operator
t1.printData();
t2.printData();
t2.setVal(3);
t2.setPtrVal(3);
t1.printData();
t2.printData();
return 0;
}
Output 1: (works as expected)
id = 1
val = 0
ptr = 0x204dc20
*ptr = 0
id = 2
val = 2
ptr = 0x204dc40
*ptr = 2
id = 1
val = 0
ptr = 0x204dc20
*ptr = 0
id = 2
val = 0
ptr = 0x204dc40
*ptr = 0
id = 1
val = 0
ptr = 0x204dc20
*ptr = 0
id = 2
val = 3
ptr = 0x204dc40
*ptr = 3
Main 2:
int main()
{
Test t1(10, 15);
{
Test t2 = t1;
t2.printData();
}
t1.printData();
return 0;
}
Output 2 (does not work as expected):
id = 1
val = 15
ptr = 0xd6fc20
*ptr = 10
id = 1
val = 15
ptr = 0xd6fc20
*ptr = 0
*** Error in `./a.out': double free or corruption (fasttop): 0x0000000000d6fc20 ***
This is weird. For some reason, the pointer points to the same memory, and the id
field is the same. It should be different. It appears that the default assignment operator is invoked. I don't know why this is the case.
Don't try to criticize the program itself. This is just a test for educational purposes. I set this up on purpose so that I would have a double free bug. The overloaded assignment operator is meant to prevent that. And it fails the second test... Why it does that?