请各位c++高手帮我看看我的程序错在那里了?

2025-02-24 00:39:57
推荐回答(5个)
回答1:

#include
#include
using namespace std;
class Person
{
public:
Person();
void display();
private:
char num[11],name[11];
};
class Teacher:public Person
{
public:
Teacher();
~Teacher();
void display();
private:
char *bm,*zc;
};
Person::Person()
{
char *p,*q;
p=new char[11];
q=new char[11];
cout<<"input the person's num and name"< cin>>p>>q;
strcpy(num,p);
strcpy(name,q);
}
void Person::display()
{
cout<<"The number:"< cout<<"The name:"<}

Teacher::Teacher()
{
char *b,*z;
b=new char[11];
z=new char[11];
cout<<"input the teacher's bumen zhichen"< cin>>b;
cin>>z;
bm=b;
zc=z;
}
void Teacher::display() //你的程序在这里出了问题.你把s2当作参数传进来,在这个函数执行完后会执行s2的析构函数,所以你在构造函数里申请的堆被释放掉
{
cout<<"The teacher's information"< Person::display();
cout<<"bumen:"< cout<<"zhichen:"<}
Teacher::~Teacher()
{
delete[] bm;
delete[] zc;

}
void main()
{
Teacher s2;
s2.display();

}
//你可以把你程序里析构函数加上打印语句,你会发现你的析构函数执行了2次,所以会释放掉申请在堆上的空间,事实上display不需要带参数也是可以的,你可以好好研究下继承之间的关系以及拷贝构造函数,你就会更明白了.
//你在构造函数里申请的堆空间就是b=new char[11]; 将会一直存在除非你delete[] bm;掉,这一点从你程序能cout它们就可以证明,你的程序出错是因为你的把teacher当作display参数,执行完这个函数,申请的堆空间就会被delete掉,以后再使用程序就出错了

回答2:

sorry

回答3:

I don't know, sorry.

回答4:

问题出在Teacher那个类当中,来看Teacher类的定义。

class Teacher: public Person
{
public:
Teacher();
~Teacher();
void display(Teacher s);
private:
char *bm,*zc; //注意这里你设置了两个指针变量
};

上述的代码目前看来一切都好,然而使用*bm和*zc造成了隐患,继续来看Teacher类的构造函数:

Teacher::Teacher()
{
char *b,*z;
b=new char[11]; //动态分配的内存空间,生命周期仅在过程内
z=new char[11]; //动态分配的内存空间,生命周期仅在过程内
cout<<"input the teacher's bumen zhichen"< cin>>b>>z;
bm=b; //就是此处出错啦(见下面的解释)
zc=z; //就是此处出错啦(见下面的解释)
}

就是此处出错的解释:bm是一个私有成员,我们可以把它看作是一个类内部的全局变量,在调用析构函数或类实例被销毁之前它会一直存在,但是b所指向的内存空间是动态生成的,仅在Teacher()这个函数中生存,在函数返回的时候,它会被自动释放,因此出现了这个问题:bm只是一个指针,它并不能保存字符串的值而只能指向保存了这个字符串的内存,解除引用时取得内存中数据,而b所指向的空间在Teacher()返回时就被销毁了,因此这时bm和zc实际上指向的是一个毫无意义的地址空间了,也就是在构造函数之后再次使用bm或zc得时候,你将得到一个不正确的结果,估计是乱码吧。

Person类不存在这个问题

char num[11],name[11]; //这句话声明了两个数组

在构造函数里

Person::Person()
{
char *p,*q;
p=new char[11];
q=new char[11];
cout<<"input the person's num and name"< cin>>p>>q;
strcpy(num,p); //不会造成问题
strcpy(name,q); //不会造成问题
}

不会造成问题的解释:虽然p、q所指向的空间在构造函数返回时会被销毁,但是num并不是指针变量,strcpy函数是将内存中的值复制给了num,因此num即便在构造函数调用完成之后依然可用。

真正写程序估计不会这么为私有数据初始化的,这个问题看起来好像一个考题,找错的,我理解就是要你注意在类内部局部变量的生存周期,特别要注意堆区动态分配的内存和指针变量,一旦将局部动态申请的空间地址赋给外部指针变量,过程结束时便会造成指针引用无意义的问题。

回答5:

flying_search的回答正确,
Bensunlight中的“在调用析构函数或类实例被销毁之前它会一直存在,但是b所指向的内存空间是动态生成的,仅在Teacher()这个函数中生存,在函数返回的时候,它会被自动释放”不对,生命期指的是变量,即char *p,*q; 的p,q生命结束,new申请的空间不会自动销毁,如果没用delete释放,就会造成内存泄漏