The problem I think is with returning an object when i overload the + operator. I tried returning a reference to the object, but doing so does not fix the memory leak. I can comment out the two statements:
dObj = dObj + dObj2;
and
cObj = cObj + cObj2;
to free the program of memory leaks. Somehow, the problem is with returning an object after overloading the + operator.
#include <iostream>
#include <vld.h>
using namespace std;
class Animal
{
public :
Animal() {};
virtual void eat() = 0 {};
virtual void walk() = 0 {};
};
class Dog : public Animal
{
public :
Dog(const char * name, const char * gender, int age);
Dog() : name(NULL), gender(NULL), age(0) {};
virtual ~Dog();
Dog operator+(const Dog &dObj);
private :
char * name;
char * gender;
int age;
};
class MyClass
{
public :
MyClass() : action(NULL) {};
void setInstance(Animal &newInstance);
void doSomething();
private :
Animal * action;
};
Dog::Dog(const char * name, const char * gender, int age) : // allocating here, for data passed in ctor
name(new char[strlen(name)+1]), gender(new char[strlen(gender)+1]), age(age)
{
if (name)
{
size_t length = strlen(name) +1;
strcpy_s(this->name, length, name);
}
else name = NULL;
if (gender)
{
size_t length = strlen(gender) +1;
strcpy_s(this->gender, length, gender);
}
else gender = NULL;
if (age)
{
this->age = age;
}
}
Dog::~Dog()
{
delete name;
delete gender;
age = 0;
}
Dog Dog::operator+(const Dog &dObj)
{
Dog d;
d.age = age + dObj.age;
return d;
}
void MyClass::setInstance(Animal &newInstance)
{
action = &newInstance;
}
void MyClass::doSomething()
{
action->walk();
action->eat();
}
int main()
{
MyClass mObj;
Dog dObj("Scruffy", "Male", 4); // passing data into ctor
Dog dObj2("Scooby", "Male", 6);
mObj.setInstance(dObj); // set the instance specific to the object.
mObj.doSomething(); // something happens based on which object is passed in
dObj = dObj + dObj2; // invoke the operator+
return 0;
}
you need to declare copy constructor since you are returning object in overloaded operator +, the compiler automatically generates one for you if you dont explicitly define it, but compiler are stupid enough to not do deep copy on pointers
to summarize your mistake in the code posted:
1.) No Copy-Constructor/Assignment-Operator defined (deallocation exception/ memory leak here)
Since you are dealing with pointers, the compiler generated functions only perform shallow copy.
It is you job to make sure such behavior is intended, otherwise redefine it yourself into :
2.) Poor handling on pointer passed in (Memory leak here)
You performed allocation before verifying null state on input parameters.
It is smart move to additionally extra allocate 1 char of memory but you do not deallocate them after finding input parameters are null. A simple fix similar to copy-constructor above will be :
3.) Improper pairing of allocator/deallocator (Potential memory leak here)
Array allocation with new[] should match with array deallocation delete[], otherwise destructor for array element will not be handled correctly.
However, to be consistent with sample code posted above using strdup (which internally make use of malloc), your destructor should be as below :