当我从代码中删除析构函数时,输出就像我想要的那样但是如果我手动释放空间程序会变得疯狂:(请有人帮助我,我使用Code :: Blocks IDE并运行在Linux mint OS
#include<iostream>
#include<cstring>
using namespace std;
class str
{
char *p;
int len;
public:
str() {
len=0;
p=NULL;
}
str(const char *s);
str(const str &s);
~str() {
cout<<" Distructor Called ";
delete p;
}
friend str operator+(const str &s,const str &t);
friend bool operator<=(const str &s,const str &t);
friend void show(str &s);
};
str::str(const char *s)
{
len=strlen(s);
p=new char[len+1];
strcpy(p,s);
}
str::str(const str &s)
{
len=s.len;
p=new char[len+1];
strcpy(p,s.p);
}
void show(str &s)
{
cout<<s.p;
}
str operator+(const str &s,const str &t)
{
str tem;
tem.len=s.len+t.len;
tem.p=new char[tem.len+1];
strcpy(tem.p,s.p);
strcat(tem.p,t.p);
return tem;
}
bool operator<=(const str &s,const str &t)
{
if(s.len<=t.len)
return true;
else
return false;
}
int main()
{
str s1="New ";
str s2="York";
str s3="Delhi";
str string1,string2,string3;
string1=s1;
string2=s1+s2;
string3=s1+s3;
cout<<"\nString1 = ";
show(string1);
cout<<"\nString2 = ";
show(string2);
cout<<"\nString3 = ";
show(string3);
cout<<"\n\n";
if(string1<=string2) {
show(string1);
cout<<" Smaller Than ";
show(string2);
cout<<"\n";
} else {
show(string3);
cout<<"Smaller Than ";
show(string1);
cout<<"\n";
}
return 0;
}
答案 0 :(得分:2)
了解Rule of Three。 如果未声明赋值运算符,编译器将生成默认值,执行以下操作:
从赋值运算符的参数的相应成员中分配所有对象的成员,调用对象的类类型成员的复制赋值运算符,并执行所有非类型的明确赋值(例如int或指针) )数据成员。
首先,上面的粗体文字适用于您班级中的char * p。 在operator +函数中,tem是堆栈上的对象。当函数结束时,tem超出范围,并调用其析构函数。 所以会发生什么是string1的p根据编译器生成的默认赋值运算符分配tem的p,这意味着string1的p指向与tem的p相同的内存位置,在它超出范围后被释放!因此,string1没有预期的值。稍后,当string1超出范围并调用其析构函数时,第二次在同一内存位置调用delete,从而导致显示错误。同样,对于string2。
如果你像这样重载赋值运算符,情况会很好:
void str::operator=(const str&s) {
delete[] p;
len=s.len;
p=new char[len+1];
strcpy(p,s.p);
}
在这种情况下,tem的p将在调用析构函数之前被复制。
注意:强>
答案 1 :(得分:1)
您没有重载赋值运算符。因此,相同的指针被分配并被删除两次导致异常。