为什么代码在析构函数中失败?

Why is the code failing in the Destructor?

我已经完成了类似于 "Why is the destructor called twice?" 的 Whosebug 问题。我的问题可能与此类似,但有细微的变化。当 运行 执行以下代码时出现错误:

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;
}

我调试了代码,发现主函数退出时第二次调用析构函数时出现错误。

1) 我想知道代码为什么会失败运行?

2) 是否存在内存泄漏?

3) 如何修复正确释放内存的错误?

提前致谢。

更新:

根据这三个规则,我还添加了一个复制构造函数并重载了赋值运算符。但是错误(表达式:_crtisvalidheappointer(puserdata))正在上升。检查 Google 后,我可以看到某些地方发生了堆损坏。当我在 createNode() 中评论 Struct 成员 employee 的初始化时,我可以看到在尝试释放析构函数中的员工时引发的错误。所以我怀疑问题出在员工结构成员身上。请帮助我 this.I 正在使用 Visual studio 进行调试和 运行ning.

您的问题是 class 中缺少复制构造和赋值运算符。结果,您多次释放 class 中的字符串。

刚刚尝试了您的代码并发现了一些导致崩溃的问题:

1) strlen returns 没有空终止字符的字符串长度,但是 strcpy 需要额外的字节,所以你的分配应该是这样的:

name = (char*)malloc(strlen(obj.name)+1);

2)当你复制employee时,你复制了指针,所以你有内存泄漏和employee 悬空指针。

malloc 也不能与构造函数一起使用,因此在

employee = (struct Employee*)malloc(sizeof(obj.employee));

员工里面有垃圾。