2012-10-12 133 views
1

我自己寫字符串類。我重載+運算符。它的工作正常,但後來我試圖eguate cstr = str +pop,它什麼也沒做。 `你可以在main()函數中看到我的錯誤。編譯器不會給出任何錯誤。重載運算符+。字符串類

#include <iostream> 
#include <string.h> 
#include <stdlib.h> 

using namespace std; 

class S { 

public: 
      S(); 
      S(const char *str); 
      S(const S &s); 

     ~S() { delete []string;} 
      S &operator =(const S &s); 

      int lenght() const {return l  ;} 
     char* strS() const {return string;} 

     friend ostream &operator <<(ostream &, const S &first) {cout<<first.string;} 
     friend S operator+ (const S& first, const S& second); 

private: 
      char *string; 
      int l; 

}; 

int main(){ 
S pop("Q6"); 
S str("M5"); 

S cstr = str +pop; // works correct 
cout<<str; 

str = str + pop; 
cout<<str ;  // doesnt work, it doesnt write in terminal 

return 0; 
} 
S::S() 
{ 
    l = 0; 
    string = new char[1]; 
    string[0]='\0'; 
} 

S::S(const char *str) 
{ 
    l  = strlen(str); 
    string = new char[l+1]; 
    memcpy(string, str, l+1); 
} 

S::S(const S &s) 
{ 
    l = s.l; 
    string = new char[l+1]; 
    memcpy(string,s.string,l+1); 
} 

S &S::operator=(const S &s) 
{ 
    if (this != &s) 
    { 
     delete []string; 
     string = new char[s.l+1]; 
     memcpy(string,s.string,s.l+1); 
     return *this; 
    } 
    return *this; 
} 

S operator +(const S& first, const S& second) 

{ 
    S temp; 
    temp.string = strcat(first.strS(),second.strS()); 
    temp.l  = first.lenght() + second.lenght(); 

    return temp; 
} 

我很期待您的幫助。

回答

3

您的運營商都有漏洞!

S temp; 
//^^^^ has only one byte buffer!!! 
temp.string = strcat(first.strS(),second.strS()); 
// 1 byte ^^^^^ strcat appends second.strS to first.strS 

你應該對於臨時重新分配內存:

S temp; 
temp.l  = first.lenght() + second.lenght(); 
delete [] temp.string; // !!!! - 
temp.string = new char[temp.l + 1]; // !!!! 
// you should have another c-tor which can allocate memory!!! 
// like: S(unsigned length, unsigned char c = '\0') 
strcpy(temp.string, first.strS()); 
strcat(temp.string, second.strS()); 

除了這個明顯的bug - 你也應該採取例外的照顧 - std::bad_alloc例如。查看複製交換習慣用法,以便更好地完成此任務。

+1

如果'new char [temp.l + 1]'失敗,您的解決方案將會有未定義的行爲。像這樣在一個字符串中亂七八糟是解決問題的肯定祕訣。 (在這種情況下,我會偶爾定義一個私有的無操作構造函數,它可以用來創建臨時文件,但這很少有必要) –

+0

@JamesKanze同意這就是爲什麼我添加了最後一句 - 建議使用copy-並交換成語,並關心異常。 – PiotrNycz

2

the manpage for strcat

The strcat() and strncat() functions append a copy of the null-terminated 
string s2 to the end of the null-terminated string s1, then add a termi- 
nating `\0'. The string s1 must have sufficient space to hold the 
result. 

,如果它分配空間,一個新的字符數組你使用它,然後填充它。但是,它並沒有這樣做。

0

問題是與你的實現operator+strcat()將由第二個參數創建的字符串追加到第一個參數指向的字符串中。返回值是第一個參數。因此,從operator+返回的結果S和第一個S參數將指向相同的緩衝區。稍後將被刪除兩次......

1

的問題是,你的operator+不會爲合併字符串分配任何內存。它也不會將字符串複製到正確的位置(它將字符串複製到第一個,而不是temp)。你有沒有簡單的解決方案。

0

檢查描述strcat。它將第一個參數 附加到第二個參數,假設兩個參數都是以空字符結尾的字符串,並返回 第一個參數。你的情況:

  • 追加到第一的string成員,雖然沒有 它(未定義行爲)enoguh內存和

  • 它集string指針temp點與 相同的內存在first;第一個被破壞離開其他 指向已刪除的內存,並分配在構造函數temp的內存泄漏。

而且,你永遠不會'\0'終止您的字符串,所以strcat可以做 任何事情。

更好的解決方案是先執行+=,然後在 中定義+條款。+=將不得不增加它的內存,並將第二個字符串的 文本追加到它。

雖然我在這裏:你的operator=也不起作用。如果new 失敗(投擲std::bad_alloc),它將 將對象置於不能被破壞的狀態。您必須確保在delete之前可能發生故障的所有操作 出現。 (事實上​​,你需要 測試自我分配是一個警告標誌。在正確書寫的賦值運算符中,這個測試非常少見。)在 這種情況下,交換習慣用法可能是你最好的選擇:複製 在局部變量中構造一個新的S,然後交換它們的成員。