2017-03-23 7 views
1

MyStringクラスを定義しました。これで追加演算を実装します。メモリリークが起こるのは恐ろしいことです。したがって、私はデストラクタから動的に割り当てられたポインタを解放しました。私は、コードをコンパイルし、それを実行した場合動的割り当てポインタを持つクラスに演算子のオーバーライドを適用します。

#include <iostream> 

class MyString { 
private: 
    int _size; 
    char* _str; 

public: 
    MyString() { 
     _size = 0; 
     _str = nullptr; 
    } 

    MyString(int size, char* str) { 
     _size = size; 
     _str = new char[size + 1]; 
     strcpy(_str, str); 
    } 

    ~MyString() { 
     delete[] _str; 
    } 

    void print() { 
     std::cout << _str << std::endl; 
    } 

    friend MyString operator+(const MyString& lhs, const MyString& rhs); 
}; 

MyString operator+(const MyString& lhs, const MyString& rhs) { 
    char* temp = new char[lhs._size + rhs._size + 1]; 
    strcpy(temp, lhs._str); 
    strcat(temp, rhs._str); 

    MyString ret(lhs._size + rhs._size, temp); 
    delete[] temp; 
    return ret; 
} 

int main() { 
    MyString first(5, "first"); 
    MyString second(6, "second"); 
    MyString add = first + second; 

    first.print(); 
    second.print(); 
    add.print(); 
} 

しかし、first.print()second.print()がうまく印刷されますが、add.print()はゴミ値を出力します、そしてクラッシュ(デバッグアサートに失敗しました!)。

出力:

first 
second 
硼硼硼硼硼硼硼硼?흚 (and creashes :(..) 

私は注釈を付けやデストラクタを実行した場合、それはうまく印刷しますが、メモリリークが発生します。なぜこうなった?私は、演算子オーバーライドのいくつかの例を見てきましたが、ポインタの動的割り当ての例は見つかりませんでした。

どのような提案も高く評価されます!この関数 'RET' の終わりにエラー 〜MYSTRING(){}

+4

[3,5、および0のルール](http://en.cppreference.com/w/cpp/language/rule_of_three)については、おそらく学習する必要があります。 3つのルールを実装するだけで、問題を解決することができます。 –

+0

ありがとう!デフォルトのコピーコンストラクタを追加すると、チャームのようにうまく動作します。 – youngminz

答えて

2
MyString operator+(const MyString& lhs, const MyString& rhs) { 
    char* temp = new char[lhs._size + rhs._size + 1]; 
    strcpy(temp, lhs._str); 
    strcat(temp, rhs._str); 

    MyString ret(lhs._size + rhs._size, temp); 
    delete[] temp; 
    return ret; 
} 

がデストラクタを呼び出し、バッファを削除た破壊された理由

0
#include<iostream> 

using namespace std; 
class Mystring{ 

private: 
    int size; 
    char *str; 

public: 
    friend Mystring operator*(const Mystring &a, const int &d); 
    friend Mystring operator+(const Mystring &a, const Mystring& b); 

    friend ostream& operator << (ostream &os, const Mystring a); 
    friend istream& operator >> (istream &is, const Mystring a); 


Mystring (int a, char b) { 
    this->size = a; 
    this->str = new char(a); 
    for (int i = 0; i < a; i++) { 
     this->str[i] = b; 
    } 
} 
~Mystring() {} 

}; 

Mystring operator+(const Mystring &a, const Mystring& b) { 

Mystring c(a.size + b.size, { 0 }); 
for (int i = 0; i < a.size; i++) 
{ 
    c.str[i] = a.str[i]; 
} 
for (int i = 0; i < b.size; i++) 
{ 
    c.str[a.size + i] = b.str[i]; 
} 
return c; 
} 
Mystring operator*(const Mystring& a,const int &d){ 

int z = a.size*d; 
Mystring c(z, { 0 }); 
int k=0; 
for (int j = 0; j < d; j++) 
{ 
    for (int i = 0; i < a.size; i++) 
    { 
     c.str[k+i] = a.str[i]; 

    } 
    k = a.size + k; 
} 
return c; 
} 

ostream& operator << (ostream &os, const Mystring a) { 

os << "["; 

int i; 
for (i = 0; i < a.size; i++) 
{ 
    os << a.str[i]; 
} 

os << "]"; 
return os; 
} 
istream& operator >> (istream &is, const Mystring a) { 

for (int i = 0; i < a.size; i++) 
{ 
    cout << i << "번째 문자 : "; 
    is >> a.str[i]; 
} 
return is ; 
} 


int main() 
{ 
int aSize, bSize, iter; 
char aInit, bInit; 

cout << "문자열A의 크기와 초기문자를 입력: "; 
cin >> aSize >> aInit; 
Mystring str1(aSize, aInit); 
cout << str1 << endl; 

cout << "문자열A 입력" << endl; 
cin >> str1; 
cout << str1 << endl; 

cout << "문자열B의 크기와 초기문자를 입력: "; 
cin >> bSize >> bInit; 
Mystring str2(bSize, bInit); 
cout << str2 << endl; 

cout << "문자열B 입력" << endl; 
cin >> str2; 
cout << str2 << endl; 

cout << "문자열A와 문자열B 합치기 : "; 
Mystring str3 = str1 + str2; 
cout << str3 << endl; 

cout << "문자열A 반복횟수 입력 : "; 
cin >> iter; 
Mystring str4 = str1*iter; 
cout << str4 << endl; 

}

enter code here 

。返されるのは、 'ret'からコピーされたMyStringの新しいインスタンスで、そのバッファは元のものと同じメモリ位置を指します。これは削除されているので、今はゴミを印刷しています。

あなたは、バッファがコピーされていることを確認するためにコピーコンストラクタを追加することができ、この問題を解決するには、次の

class MyString { 

// Other class details 
public: 
    MyString(const MyString & other) : MyString(other._size, other._str) {} 

// Other class details 
} 

これは、1つのMyStringが別のMyStringに代入されたときにバッファがコピーされていることを確認します。

+0

ようこそスタックオーバーフロー!この質問は、単にコードのためのものではなく*説明*を探しています(このコード*は正しく動作しません - あなたが本質的な 'delete []'を削除したために漏れます)。あなたの答えは質問者のための洞察を提供せず、削除されるかもしれません。観察された症状の原因を説明するために[編集]してください。 –

関連する問題