重新初始化字符串对象时发生崩溃

crash happens while re-initializing a string object

本文关键字:崩溃 对象 初始化 字符串      更新时间:2023-10-16

请您深入了解下面提供的字符串类程序

class String{
private: int len;
         int size;
         char *p;
public:  
     int getlen()
     {
         return len;
     }
     int getsize()
     {
         return size;
     }
     char* getp()
     {
         return p;
     }
     String(char *p1=0)
     {
         cout<<"constructor called"<<endl;
         if(p1!=0)
         {
            len=strlen(p1);
            size=len+1;
            p=new char(sizeof(char)*(size));
            strncpy(p,p1,size);
         }
         else
         {
             len=size=0;
             p="";
         }
     }
     String(String &s1)
     {
         cout<<"copy constructor called"<<endl;
         if(&s1!=this)
         {
             cout<<"copy constructor called"<<endl;
             len=s1.getlen();
             size=len+1;
             p=new char(sizeof(char)*(size));
             //char *d=s1.getp();
             strncpy(p,s1.getp(),size);
         }
     }
     void display()
     {
         cout<<"string len="<<len<<endl;
         cout<<"string size="<<size<<endl;
         cout<<"string name="<<p<<endl;
     }
     ~String()
     {
         cout<<"destructor called"<<endl;
         if(strlen(p) >= 1)
         {
            cout<<"111"<<endl;
            delete []p;
         }
         //cout<<"destructor finished"<<endl;
     }
};
int main(int argc, char *argv[])
{
  String s1;
  String s2("hello");
  s1.display();
  s2.display();
  s2=String("Hello World");
  s2.display();
  return 0;
}

请查看重新初始化行

     s2=String("Hello World");

String("Hello World")将创建一个临时的字符串对象,它应该调用赋值运算符。由于编译器的默认赋值运算符将执行浅拷贝,因此在临时 String 对象超出范围后,String 类中存在的 char 指针将变为 NULL。

我试图重载赋值运算符,如下所示

 String& operator =(String &s1)
 {
     cout<<"operator = called"<<endl;
     if(&s1!=this)
     {
         len=s1.len;
         size=s1.size;
         if(strlen(p)>=1)
              delete p;
         p=new char(sizeof(char)*size);
         strncpy(p,s1.getp(),size);
     }
     return *this;
  }

但它给出的错误与"运算符="不匹配(操作数类型为"字符串"和"字符串") s2=字符串("世界");

要求您在更正"operator="后编译程序,因为我怀疑复制构造函数可能会给出任何错误。

提前谢谢..

一个问题是这一行:

p=new char(sizeof(char)*(size));

您需要改用方括号:

p=new char[sizeof(char)*(size)];
          ^                   ^

其次,对于复制构造函数和赋值运算符,参数类型应该是 const 限定引用,也称为 const String& ,而不仅仅是 String& 。此外,作为良好做法,任何不修改任何成员变量(如 displaygetp)的方法都应该在函数声明的末尾(即在{之前)有一个const