2016-03-20 30 views
0

Microsoft Visual Studio 2015 kullanarak C++'mda kendi String sınıfımı yazmaya çalıştım. Bu sınıfı şöyle yazdım;Bellek sızıntısı var mı?

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

Bunu yapmaya çalıştığımda iyi çalışıyor;

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

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

Ama bellekten yeni alanı ayrılıyor am hat char* newContent = new char[newSize]; yılında operator+ işlevinde herhangi bellek sızıntısı olup olmadığından emin değilim ve ben iade deyimi return myString(newContent); içinde olması gerekiyor.

Bu nedenle bu satırdan önce tahsis edemiyorum ve iade ifadesinden sonra tahsis edemiyorum. Doğru mu, hafıza sızıntısı var mı? Eğer öyleyse, bunu nasıl düzeltebilirim?

DÜZENLEME 1: Prens Dhaliwal yardımıyla aşağıdaki gibi ben operator+ işlevini değiştirdik ; Ben temp oluşturulan beri

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

Ama yerel onu dönmeden önce kendi yıkıcı çağırır ve hata veriyor. Hafızam için de hafıza ayırmam gerek. Ve işlevi şu şekilde değiştirdim;

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

Şimdi gayet iyi çalışıyor, ama ben çünkü temp değişkenin bellek sızıntısı hala olduğuna inanıyoruz. Bir bellek sızıntısı varsa, bunu nasıl düzeltebilirim?

DÜZENLEME 2: Ben sadece kodunda bir bellek sızıntısı aslında var olan bir Kopya Oluşturucu

+0

Kodunuzu kodlayın, sonra bir bellek sızıntısı olup olmadığını öğrenin. Eğer öyleyse, nerede bulmaya çalışabilirsiniz. – ferit

+1

STL bir dize sınıfına sahipken bunu neden yaptın? – duffymo

+0

Aslında bu benim ev ödevimden ve onları kullanmamızı yasakladı. Öğrenme amaçları için sanırım. –

cevap

0

oluşturarak çözdüm. s + " string"'da + işlecini kullanırken. senin operator+() tanımı yani

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

yılında Burada char* newContent = new char[newSize]; yeni dize tahsis yeni dizeye eski ve yeni bölümünü kopyaladığınız. Ve yine yeni dizeyi kurucu return myString(newContent);'a ayırıyorsunuz. Ama eski dizini nerede siliyorsun? Kodunun hiçbir yerinde yok. Yani newContent dizesini silmeniz gerekir. Sen Bir kopya kurucu oluşturmak zorunda bu

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

GÜNCELLEME yapabilirsiniz.

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

Cevabınız için teşekkürler! Bu arada, '\ 0' karakteri nedeniyle newContent için belleği ayırırken newSize + 1 yazmamalıyız. –

+0

Ayrıca, geçici dizeyi yerel olarak oluşturduk. Bu operatör + işlevi bittiğinde, temp'ın yıkıcısını çağırır. Bunu nasıl halledeyim? –

+0

Temp'in yıkıcısı çağrılmadan önce, yerel değişkenin kopyasını iade ettiğiniz için kopyalanır. – 0x0001