2016-03-20 14 views
0

Ich habe versucht, meine eigene String-Klasse in C++ mit Microsoft Visual Studio 2015 zu schreiben. Ich schrieb die Klasse so;Gibt es ein Speicherleck?

#include<string.h> 
class myString { 
    private: 
     char* content; 
    public: 
     int size; 
     myString(); 
     myString(char*); 
     ~myString(); 
     bool operator==  (const myString &) const; 
     bool operator!=  (const myString &) const; 
     myString operator= (const myString &); 
     myString operator+ (const myString &) const; 
     myString operator+= (const myString &); 
     friend std::ostream& operator<< (std::ostream &os, const myString &); 
     char operator[] (int &) const; 
}; 

std::ostream& operator<<(std::ostream &os, const myString &string) { 
    os << string.content; 
    return os; 
} 

myString::myString() { 
    size = 0; 
    content = "\0"; 
} 

myString::myString(char* newContent) { 
    size = strlen(newContent); 
    content = new char[size+1]; 
    strcpy(content, newContent); 
} 

myString::~myString() { 
    delete[] content; 
} 

myString myString::operator= (const myString &string) { 
    if (size != string.size) { 
     delete[] content; 
     size = string.size; 
     content = new char[size+1]; 
    } 
    strcpy(content, string.content); 
    return *this; 
} 

bool myString::operator== (const myString &string) const { 
    if (size != string.size) 
     return false; 
    if (strcmp(content, string.content)) 
     return false; 
    return true; 
} 

bool myString::operator!= (const myString &string) const { 
    if (*this == string) 
     return false; 
    return true; 
} 

myString myString::operator+ (const myString &string) const { 
    int newSize = size + string.size; 
    char* newContent = new char[newSize]; 
    strcpy(newContent, content); 
    strcat(newContent, string.content); 
    return myString(newContent); 
} 

myString myString::operator+= (const myString &string) { 
    *this = *this + string; 
    return *this; 
} 

char myString::operator[] (int &index) const { 
    return content[index]; 
} 

Es funktioniert gut, wenn ich versuchte, dies zu tun;

#include<iostream> 
#include "MyString.h" 
using namespace std; 

int main() { 
    myString s("my new"); 
    cout << s+" string" << endl;  
} 

Aber ich bin mir nicht sicher, ob es ein Speicherverlust in der Leitung in operator+ Funktion ist char* newContent = new char[newSize]; ich neuen Raum aus dem Speicher bin Aufteilung und ich brauche es in der return-Anweisung return myString(newContent);.

So kann ich es nicht vor dieser Zeile freigeben und ich kann es nach der Rückkehranweisung nicht freigeben. Habe ich Recht, gibt es ein Speicherleck? Wenn ja, wie kann ich das beheben?

EDIT 1: ich die operator+ Funktion geändert haben, wie mit Hilfe von Prince Dhaliwal folgt;

myString myString::operator+ (const myString &string) const { 
    myString temp; 
    int newSize = size + string.size; 
    char* newContent = new char[newSize + 1]; 
    temp.size = newSize; 
    strcpy(newContent, content); 
    strcat(newContent, string.content); 
    temp.content = newContent; 
    return temp; 
} 

Aber da ich die temp lokal erstellt nennt es seine destructor, bevor er zurückkehrt und gibt Fehler. Ich nehme an, ich sollte auch Speicher für die Temperatur zuweisen. Und ich habe die Funktion wie folgt geändert;

myString myString::operator+ (const myString &string) const { 
    myString* temp= new myString; 
    int newSize = size + string.size; 
    char* newContent = new char[newSize+1]; 
    temp->size = newSize; 
    strcpy(newContent, content); 
    strcat(newContent, string.content); 
    temp->content = newContent; 
    return *temp; 
} 

Es funktioniert jetzt gut, aber ich glaube, dass es nach wie vor wegen der temp variablen Speicherverlust ist. Wenn es einen Speicherverlust gibt, wie kann man das beheben?

EDIT 2: Ich habe es einfach festgelegt durch ein Kopierkonstruktor Schaffung

+0

Profilieren Sie Ihren Code, dann wissen Sie, ob es ein Speicherleck gibt. Wenn ja, können Sie versuchen, wo zu finden. – ferit

+1

Warum sollten Sie das tun, wenn STL eine String-Klasse hat? – duffymo

+0

Eigentlich ist das von meinen Hausaufgaben und sie verboten uns, sie zu benutzen. Ich denke für die Lernzwecke. –

Antwort

0

Es ist eigentlich ein Speicherleck in Ihrem Code. Wenn Sie den Operator + in s + " string" verwenden. In Ihrer operator+() Definition heißt

myString myString::operator+ (const myString &string) const { 
    int newSize = size + string.size; 
    char* newContent = new char[newSize]; 
    strcpy(newContent, content); 
    strcat(newContent, string.content); 
    return myString(newContent); 
} 

Sie die Zuweisung der neuen Zeichenfolge hier char* newContent = new char[newSize];, das Kopieren der älteren und neuen Teil auf die neue Zeichenfolge. Und wieder vergeben Sie die neue Zeichenfolge im Konstruktor return myString(newContent);. Aber wo löschst du deine alte Zeichenfolge? Es ist nirgendwo in deinem Code. Sie müssen also die Zeichenfolge newContent löschen. Sie können dies tun

myString myString::operator+ (const myString &string) const { 
    myString temp; 
    int newSize = size + string.size; 
    char* newContent = new char[newSize + 1]; 
    temp.size = newSize; 
    strcpy(newContent, content); 
    strcat(newContent, string.content); 
    temp.content = newContent; 
    return temp; 
} 

UPDATE Sie haben einen Copy-Konstruktor zu erstellen.

myString(const myString &rhs) : 
size(rhs.size) { 
    content = new char[size + 1]; 
    strcpy(content, rhs.content); 
} 
+0

Danke für die Antwort! Übrigens sollten wir newSize + 1 nicht schreiben, wenn wir den Speicher für newContent wegen des '\ 0'-Zeichens zuweisen? –

+0

Außerdem haben wir die temporäre Zeichenfolge lokal erstellt. Wenn diese Operator-Funktion beendet ist, ruft sie den Destruktor von temp auf. Wie soll ich damit umgehen? –

+0

Bevor der Destruktor von 'temp' aufgerufen wird, wird er kopiert, während Sie die Kopie der lokalen Variablen zurückgeben, was in Ordnung ist. – 0x0001