2017-03-23 3 views
1

J'ai défini la classe MyString et maintenant je souhaite implémenter l'opération d'ajout. C'est horrible pour les fuites de mémoire, alors j'ai pris soin de libérer les pointeurs dynamiquement alloués du destructeur.Appliquer l'opérateur redéfinissant les classes avec des pointeurs d'allocation dynamique

#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(); 
} 

Cependant, si je compile le code et l'exécuter, l'est bien imprimé first.print() et second.print(), mais le add.print() affichera la valeur des déchets, et les accidents (Debug Assertion Failed!).

Sortie:

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

Si j'annoter et lance le destructor, il imprime bien, mais une fuite de mémoire se produit. Pourquoi cela arrive-t-il? J'ai regardé plusieurs exemples de substitution d'opérateur, mais je n'ai pas trouvé un exemple de cette allocation dynamique de pointeurs.

Toute suggestion sera grandement appréciée!

+4

Vous devriez probablement en savoir plus sur [les règles de trois, cinq et zéro] (http://en.cppreference.com/w/cpp/language/rule_of_three). La mise en œuvre de la règle des trois devrait suffire à résoudre votre problème. –

+0

Merci! Ajoutant le constructeur de copie par défaut, cela fonctionne bien comme des charmes. – youngminz

Répondre

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; 
} 

A la fin de cette fonction 'ret' est détruite qui appelle la destructor et supprime le tampon . Ce qui est retourné est une nouvelle instance de MyString qui a été copiée à partir de 'ret', et son pointeur pointe vers le même emplacement de mémoire que l'original. Depuis que cela a été supprimé, vous imprimez maintenant des déchets.

Pour résoudre ce problème, vous pouvez ajouter un constructeur de copie pour assurer la mémoire tampon est copié:

class MyString { 

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

// Other class details 
} 

Cela permettra d'assurer le tampon est copié quand on MaChaîne est affecté à un autre MaChaîne.

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 

pourquoi erreur ~ myString() {}

+0

Bienvenue dans Stack Overflow! Cette question est à la recherche d'une * explication *, pas simplement pour le code de travail (et ce code * ne fonctionne pas correctement - il fuit parce que vous avez supprimé l'essentiel 'delete []'). Votre réponse ne fournit aucun point de vue à l'auteur de la question et peut être supprimée. S'il vous plaît [modifier] pour expliquer ce qui provoque les symptômes observés. –