2015-10-29 56 views
1

我正在为自己的作业定义自己的字符串类。这涉及到我的注意,下面的代码在C++中连接两个自定义的字符串对象?

class MyString { 
public: 
    MyString(const char* s = NULL) {len = strlen(s); str = new char[len + 1]; strcpy(str, s);} 
    ~MyString() {delete [] str;} 
    friend ostream& operator << (ostream& ost, const MyString& s) { ost << s.str; return ost;} 
    friend MyString operator + (const MyString &s1, const MyString &s2) { 
     int length = strlen(s1.str) + strlen(s2.str); 

     char *str = new char[length + 1]; 
     strcpy(str, s1.str); 
     strcat(str, s2.str); 
     return MyString(str); 
    } 
private: 
    char * str; 
    int len; 
}; 

int main() { 
    MyString s1 = MyString("hello"); 
    MyString s2 = MyString("world"); 
    cout << s1 + s2 << endl; 
    return 0; 
} 

作品,返回的对象是在最后时刻产生。但下面的代码

class MyString { 
public: 
    MyString(const char* s = NULL) {len = strlen(s); str = new char[len + 1]; strcpy(str, s);} 
    ~MyString() {delete [] str;} 
    friend ostream& operator << (ostream& ost, const MyString& s) { ost << s.str; return ost;} 
    friend MyString operator + (const MyString &s1, const MyString &s2) { 
     int length = strlen(s1.str) + strlen(s2.str); 
     MyString temp; 
     temp.str = new char[length + 1]; 
     strcpy(temp.str, s1.str); 
     strcat(temp.str, s2.str); 
     return temp; 
    } 
private: 
    char * str; 
    int len; 
}; 

int main() { 
    MyString s1 = MyString("hello"); 
    MyString s2 = MyString("world"); 
    cout << s1 + s2 << endl; 
    return 0; 
} 

不,给我一个运行时错误。所以我很困惑为什么第二种方法失败,如果一个临时对象被定义,修改并在重载操作符中返回。

+0

我强烈推荐两件事:(1)不要使用手动记忆管理;相反,环绕一个'std :: unique_ptr '。 (2)不要使用C字符串函数。使用C++标准库算法代替(特别是,这将是'std :: copy'这里。 –

+3

'MyString temp;'使用's == nullptr'的构造函数,然后'strlen(s)'是UB。 – zch

+1

请使用debugger – Drop

回答

0
在构造函数

你分配你的内存为您的字符串:

len = strlen(s); str = new char[len + 1]; strcpy(str, s); 

所以如果你追加一个字符串以后;因此没有分配内存。

创建两个字符串的总和时;你创建你的“和字符串”是这样的:

MyString temp; 

然后为str分配的内存是未知的;因为

len = strlen(NULL); 

如果你想继续;你可能会考虑增加两件事:

  • a检查s = NULL;然后不分配内存,但这会在稍后造成麻烦...
  • 分配更多内存的方法;像temp.allocate(strlen的(S1)+ strlen的(S2))
3

的问题是,当你默认,构建temp这里:

MyString temp; 

,你必须执行:

MyString(const char* s = NULL) {len = strlen(s); ... } 

strlen空指针未定义。如果你不是改变了默认参数,将工作:

MyString(const char* s = "") 

然而,这两种解决方案仍然较差,它们都泄漏内存。在前者中,你永远不会delete[]临时str。在后者中,您的默认构造函数分配了一个新的str成员,然后您立即用新分配的str成员覆盖它。原稿被泄露。

0

返回创建一个对象并复制指针。然后在同一地址发生2次删除