为什么代码在析构函数中失败?
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));
员工里面有垃圾。
我已经完成了类似于 "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));
员工里面有垃圾。