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

时间:2018-10-21 17:01:24

标签: class c++11 memory-management memory-leaks structure

我经历了类似于“为什么析构函数被调用两次?”之类的stackoverflow问题。我的问题可以是类似的问题,但变化很小。运行以下代码时出现错误:

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的初始化时,我会发现尝试释放析构函数中的employee时出现错误。所以我怀疑问题出在员工结构成员上。请帮我。我正在使用Visual Studio进行调试和运行。

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

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

1) strlen 返回不带空终止符的字符串长度,但 strcpy 需要附加字节,因此您的分配应如下所示:

foo(vee: "v") //Argument type 'String' does not conform to expected type 'Numeric'

2)复制 员工 时,您复制了指针,因此内存泄漏和 员工 作为一个悬挂的东西。

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

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

雇员 内部有垃圾。