Operator + overload object causing a memory leak, C ++

I think the problem is returning the object when I overload the + operator. I tried to return a reference to the object, but this does not fix the memory leak. I can comment on two statements:

dObj = dObj + dObj2;

and

cObj = cObj + cObj2;

to free up a memory leak program. For some reason, the problem is the return of the 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;
    }
+3
source share
11 answers

you need to declare the copy constructor, since you are returning the object in the overloaded + operator, the compiler automatically generates it for you if you do not explicitly define it, but the compiler is stupid enough not to make a deep copy on pointers.

To summarize your error in the submitted code:

1.) -/- ( / )
, .
, , , :

Dog::Dog(const Dog& ref) :
_name( strdup(ref._name) ), 
_gender( strdup(ref._gender) ), 
_age( ref._age )
{
}

Dog& Dog::operator=(const Dog &dObj)
{
    if (this != &dObj)
    {
        free (_name);
        free (_gender);
        _name = strdup( dObj._name );
        _gender = strdup( dObj._gender );
        _age = dObj._age;
    }
    return *this;
}

2.) ( )
.
1 char , , . , , :

Dog::Dog(const char * name, const char * gender, int age) :
_name( strdup(name) ), 
_gender( strdup(gender) ), 
_age( age )
{
}

3.) / ( )
new [] [], .
, , , strdup ( malloc), :

Dog::~Dog()
{
    free (_name);
    free (_gender);
    _age = 0;
}
+4

( , std::string!), , :

( , )

(, delete[], delete), , , , . , , - -.

+5

std::string, . , ++, ++. , std::string.

, char*, , . ?

+4

: + dObj.name dObj.gender , Dog d, operator+, , name gender .

+1

, :

delete[] name;
delete[] gender;
0

new char[], delete [] name;. , , .

, std::string!:)

0

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)

Dog::~Dog()
{
    delete name;
    delete gender;
    age = 0;
}

new[] delete[], delete.

0

,

Dog::~Dog()
{
    delete name;
    delete gender;
    age = 0;
}

age=0, , .

0

, . , :

dObj = dObj + dObj2;

+ dObj char * NULL ( +), char *.

0

( Dog s), , ~Dog Dog, , virutual ~Animal Animal, .

, :

Animal* a=new Dog();
delete a;

Dog .

0

, Animal . , :

Animal *dog = new Dog("Spot", "Male", 5);
delete dog;

then you will leak memory even after fixing any other problems, because without a virtual destructor in your class, the Animaldestructor Dogwill never be called to free the memory allocated in the constructor Dog.

This did not happen in your case, because you created your dogs as automatic variables on the stack, which is good.

0
source

Source: https://habr.com/ru/post/1740409/


All Articles