标签:http os io ar for 2014 问题 代码 sp
昨天写了两个程序,均出现了析构函数造成Debug Assertion Failed的问题,由于是初学c++怎么想也想不通问题出在哪里。今天早上经人指点终于明白问题所在了。下面贴出代码和问题解析:(以下内容摘自本人在csdn论坛求助的帖子)
第一个问题程序:
//Teacher_Level.h
#pragma once
#include<iostream>
using namespace std;
int num=0;
class Teacher
{
public:
char *title;
Teacher()
{
title=new char[50];
}
~Teacher()
{
cout<<"called:"<<++num<<endl;
if(title!=NULL)
{
delete[] title;
title=NULL;
}
}
};
class Level
{
public:
char *position;
Level()
{
position=new char[50];
}
~Level()
{
if(position!=NULL)
{
delete[] position;
position=NULL;
}
}
};
class Teacher_Level:public Teacher,public Level
{
public:
void show()
{
cout<<"The teacher_level:"<<endl;
cout<<"Title:";
puts(title);
cout<<"Position:";
puts(position);
}
};
//main.cpp
#include "Teacher_Level.h"
#include<iostream>
using namespace std;
int main()
{
Teacher_Level p;
p.title="professor";
p.position="header";
p.show();
return 0;
}
报错如下:
第二个问题程序:
//CShop.h
#pragma once
#include<string.h>
#include<iostream>
using namespace std;
class CShop
{
public:
char *product;
int price;
CShop();
CShop(char *CProduct,int CPrice);
~CShop();
friend ostream& operator<<(ostream& os,CShop p)
{
cout<<"Product:";
puts(p.product);
cout<<"Price:";
cout<<p.price;
return os;
}
};
CShop::CShop()
{
product=new char[50];
}
CShop::CShop(char *CProduct,int CPrice)
{
product=new char[50];
strcpy(product,CProduct);
price=CPrice;
}
CShop::~CShop()
{
if(product!=NULL)
{
delete[] product;
product=NULL;
}
}
//main.cpp
#include "CShop.h"
#include<iostream>
using namespace std;
int main()
{
char *product="book";
int price=120;
CShop p(product,price);
cout<<"The information of the shop:"<<endl;
cout<<p<<endl;
return 0;
}
报错如下:
正确解答:
第一个:
Teacher_Level p; // 这里调用了构造函数,给title分配了内存
p.title="professor"; // 这里又直接把title指向了常量区,导致析构函数里面企图delete一个常量区指针
应该照着第二个程序的思路来给title赋值。
第二个程序的问题稍微有点复杂。
friend ostream& operator<<(ostream& os,CShop p)
这里的p是按值传递的,编译器要调用拷贝构造函数来创建一个新对象。但是你自己没写拷贝构造函数,所以编译器自己生成了一个拷贝构造函数,问题由此产生,因为编译器的拷贝构造函数是所谓“浅拷贝”,简单的复制了product的地址。然后销毁这个新对象的时候就把product的地址delete了。你可能会说,delete之后把product赋值NULL了,但那是针对那个临时对象的,main里面的p的product指针没有变动,还指向最初的new的结果,然后退出main的时候就再次delete,导致出错。
把这个<<重载函数的参数改成&p可以绕过这个问题,但是根本的解决方法是自己写一个拷贝构造函数,不是简单的复制指针,而是重新new一个指针然后strcpy。
对于这两个程序的问题,我收获很大,特别是第二个让我理解了拷贝构造函数的调用机制。
C++析构函数造成Debug Assertion Failed的问题
标签:http os io ar for 2014 问题 代码 sp
原文地址:http://www.cnblogs.com/tankeee/p/3957308.html