Search code examples
classc++11memory-managementmemory-leaksstructure

Why is the code failing in the Destructor?


I have gone through stackoverflow questions similar to "Why is the destructor called twice?". My question can be a similar one but with a small change. I am getting an error when running the following code:

struct Employee{
        char *name;
        char *tag;
        Employee *employee;

        Employee(){
            name = NULL;
            tag = NULL;
            employee = NULL;
        }
        //copy constructor
        Employee(const Employee &obj){
            cout << "Copy constructor called" << endl;
            name = (char*)malloc(sizeof(char)*strlen(obj.name));
            strcpy(name, obj.name);
            tag = (char*)malloc(sizeof(char)*strlen(obj.tag));
            strcpy(tag, obj.tag);
            employee = (struct Employee*)malloc(sizeof(obj.employee));
            employee = obj.employee;
        }
        //overloaded assignment operator
        void operator = (const Employee &obj){
            cout << "Assignment operator called" << endl;
            if (this == &obj){
                return;
            }
            strcpy(name, obj.name);
            strcpy(tag, obj.tag);
            employee = obj.employee;

        }
        //destructor
        ~Employee(){
            cout << "Destructor called" << endl;
            if (name != NULL){
                cout << "Freeing name" << endl;
                free(name);
                name = NULL;
            }
            if (tag != NULL){
                cout << "Freeing tag" << endl;
                free(tag);
                tag = NULL;
            }
            if (employee != NULL){
                cout << "Freeing employee" << endl;
                free(employee);
                employee = NULL;
            }
        }
};
Employee createNode(){
        Employee emp;
        emp.name = (char*)malloc(sizeof(char)* 25);
        strcpy(emp.name, "Alan");
        emp.tag = (char*)malloc(sizeof(char)* 25);
        strcpy(emp.tag, "Engineer");
        emp.employee = (struct Employee*)malloc(sizeof(struct Employee));//just created memory, no initialization
        return emp;
}
Employee get(){
        //Employee emp = createNode();
        //return emp;
        return createNode();
}

int main(){
        Employee emp = get();

        getchar();
        return 0;
}

I debugged the code and found that error is raising when the destructor is called second time when the main function exits.

1) I want to know why the code fails to run?

2) Are there any memory leaks?

3) How can I fix the error properly deallocating memory?

Thanks in advance.

Update:

As per the three Rule I have also added a copy constructor and overloaded the assignment operator. But the error(Expression : _crtisvalidheappointer(puserdata)) is raising. After checking in the Google I could see that some where the Heap corruption is happening. When I comment the initialization of the Struct member employee in the createNode() then I could see the error raising when trying to free the employee in destructor. So I suspect the problem is with the employee struct member. Please help me with this.I am using Visual studio for debugging and running.


Solution

  • Your problem is a lack of copy construct and assignment operator in your class. As a result you are freeing the strings within the class multiple times.